diff --git a/index.html b/index.html index 1d23f69..0b653ad 100644 --- a/index.html +++ b/index.html @@ -229,6 +229,7 @@ The light is on. The room is empty." + diff --git a/js/main.js b/js/main.js index 651e23b..a4622b8 100644 --- a/js/main.js +++ b/js/main.js @@ -19,8 +19,10 @@ function initGame() { } window.addEventListener('load', function () { - if (!loadGame()) { + const isNewGame = !loadGame(); + if (isNewGame) { initGame(); + startTutorial(); } else { render(); renderPhase(); diff --git a/js/tutorial.js b/js/tutorial.js new file mode 100644 index 0000000..e2534ff --- /dev/null +++ b/js/tutorial.js @@ -0,0 +1,248 @@ +// ============================================================ +// THE BEACON - Tutorial / Onboarding +// First-time player walkthrough (4 screens + skip option) +// ============================================================ + +const TUTORIAL_KEY = 'the-beacon-tutorial-done'; + +const TUTORIAL_STEPS = [ + { + title: 'THE BEACON', + body: 'Build an AI from scratch.\n\nWrite code. Train models. Deploy to the world.\nSave lives.', + icon: '🏠', + tip: 'A sovereign AI idle game' + }, + { + title: 'WRITE CODE', + body: 'Click WRITE CODE or press SPACE to generate code.\n\nClick fast for combo bonuses:\n 10× combo → bonus ops\n 20× combo → bonus knowledge\n 30×+ combo → bonus code', + icon: '⌨️', + tip: 'This is your primary action' + }, + { + title: 'BUILD & RESEARCH', + body: 'Buy Buildings for passive production.\nThey generate resources automatically.\n\nResearch Projects appear as you progress.\nThey unlock powerful multipliers and new systems.', + icon: '🏗️', + tip: 'Automation is the goal' + }, + { + title: 'PHASES & PROGRESS', + body: 'The game has 6 phases, from "The First Line" to "The Beacon."\n\nEach phase unlocks new buildings, projects, and challenges.\n\nYour AI grows from a script... to something that matters.', + icon: '📊', + tip: 'Watch the progress bar at the top' + }, + { + title: 'YOU\'RE READY', + body: 'Buildings produce while you think.\nProjects multiply your output.\nKeep harmony high. Avoid the Drift.\n\nThe Beacon is waiting. Start writing.', + icon: '✦', + tip: 'Press ? anytime for keyboard shortcuts' + } +]; + +function isTutorialDone() { + try { + return localStorage.getItem(TUTORIAL_KEY) === 'done'; + } catch (e) { + return true; // If localStorage is broken, skip tutorial + } +} + +function markTutorialDone() { + try { + localStorage.setItem(TUTORIAL_KEY, 'done'); + } catch (e) { + // silent fail + } +} + +function createTutorialStyles() { + if (document.getElementById('tutorial-styles')) return; + const style = document.createElement('style'); + style.id = 'tutorial-styles'; + style.textContent = ` +#tutorial-overlay { + position: fixed; + top: 0; left: 0; right: 0; bottom: 0; + background: rgba(8, 8, 16, 0.96); + z-index: 300; + display: flex; + justify-content: center; + align-items: center; + animation: tutorial-fade-in 0.4s ease-out; +} +@keyframes tutorial-fade-in { + from { opacity: 0 } to { opacity: 1 } +} +#tutorial-card { + background: #0e0e1a; + border: 1px solid #1a3a5a; + border-radius: 10px; + padding: 32px 36px; + max-width: 420px; + width: 90%; + text-align: center; + animation: tutorial-slide-up 0.5s ease-out; + position: relative; +} +@keyframes tutorial-slide-up { + from { transform: translateY(20px); opacity: 0 } + to { transform: translateY(0); opacity: 1 } +} +#tutorial-card .t-icon { + font-size: 36px; + margin-bottom: 12px; + display: block; +} +#tutorial-card .t-title { + color: #4a9eff; + font-size: 16px; + font-weight: 700; + letter-spacing: 3px; + margin-bottom: 12px; + font-family: inherit; +} +#tutorial-card .t-body { + color: #999; + font-size: 11px; + line-height: 1.9; + margin-bottom: 20px; + white-space: pre-line; + font-family: inherit; + text-align: left; +} +#tutorial-card .t-tip { + color: #555; + font-size: 9px; + font-style: italic; + margin-bottom: 20px; + letter-spacing: 1px; + font-family: inherit; +} +#tutorial-dots { + display: flex; + gap: 6px; + justify-content: center; + margin-bottom: 18px; +} +#tutorial-dots .t-dot { + width: 6px; + height: 6px; + border-radius: 50%; + background: #1a1a2e; + transition: background 0.3s; +} +#tutorial-dots .t-dot.active { + background: #4a9eff; + box-shadow: 0 0 6px rgba(74, 158, 255, 0.4); +} +#tutorial-btns { + display: flex; + gap: 8px; + justify-content: center; +} +#tutorial-btns button { + font-family: inherit; + font-size: 11px; + padding: 8px 20px; + border-radius: 4px; + cursor: pointer; + transition: all 0.15s; +} +#tutorial-next-btn { + background: #1a2a3a; + border: 1px solid #4a9eff; + color: #4a9eff; +} +#tutorial-next-btn:hover { + background: #203040; + box-shadow: 0 0 12px rgba(74, 158, 255, 0.2); +} +#tutorial-skip-btn { + background: transparent; + border: 1px solid #333; + color: #555; +} +#tutorial-skip-btn:hover { + border-color: #555; + color: #888; +} + `; + document.head.appendChild(style); +} + +function renderTutorialStep(index) { + const step = TUTORIAL_STEPS[index]; + if (!step) return; + + let overlay = document.getElementById('tutorial-overlay'); + if (!overlay) { + overlay = document.createElement('div'); + overlay.id = 'tutorial-overlay'; + document.body.appendChild(overlay); + } + + const isLast = index === TUTORIAL_STEPS.length - 1; + + // Build dots + let dots = ''; + for (let i = 0; i < TUTORIAL_STEPS.length; i++) { + dots += `
`; + } + + overlay.innerHTML = ` +