Fixed issue #47 | Kripa not get autosamarpita if chetanaJagrita
मोक्ष Devlog #47 — गुरु-दीक्षा: Building a Vedic Tutorial System Without a Tutorial Framework "उद्धरेदात्मनात्मानं नात्मानमवसादयेत्।" — Bhagavad Gita 6.5 Every game needs to teach itself. But मोक्ष isn't every game. When I sat down to build the tutorial, the usual approaches felt wrong. A tooltip pointing at the UI? A "Welcome to the game!" popup? These patterns exist for games about collecting coins or shooting enemies. मोक्ष is about karma, rebirth, and liberation. The tutorial needed to feel like it belonged to that world — not borrowed from a Unity asset pack. So I didn't build a tutorial. I built गुरु-दीक्षा — the Guru's Initiation. The Problem With Most Game Tutorials Most tutorials are instruction manuals with a play button. They pause the game, show you a tooltip, unpause, and hope you remember what you just read. The problem: they break immersion. You're suddenly aware you're reading documentation, not playing a game. मोक्ष is built entirely in Vanilla JS + HTML5 Canvas — no engine, no framework, no Phaser. Everything is hand-rolled. I could have built a simple overlay system and called it done. But the game's spiritual foundation demanded something more intentional. The Design: Scripture Cards The core idea: every tutorial step is a Sanskrit shloka, not an instruction. Each step shows a scripture-style card — dark background, gold border, saffron accent line — with: A Sanskrit verse relevant to what the player is about to learn Its source (Bhagavad Gita, Ramcharitmanas, Yogavasishtha, etc.) A task in Hindi — what to actually do A hint — the Vedic meaning behind the action The card isn't a popup. It's a dīkṣā — an initiation. The player doesn't "read instructions." They receive teachings. ┌─────────────────────────────────────┐ ← gold border │ 🕉️ 1 / 5 │ ← saffron accent + step counter │ │ │ मायाजालमिदं विश्वं मोहयत्यखिलं जगत् │ ← shloka (italic, warm cream) │ — योगवासिष्ठ │ ← source (gold, subdued) │ ───────────────────────────────── │ │ ऊपर से गिरती वस्तु को स्पर्श करो। │ ← task (white) │ सुनहरी "ॐ" — नाम है, इसे ग्रहण करो।│ │ │ │ ✦ माया पहचानना — पहला कदम है। ✦ │ ← hint (muted) │ │ │ [ ENTER / TAP to continue ] │ ← saffron dismiss button └─────────────────────────────────────┘ Rendered entirely in Canvas 2D — no DOM, no CSS, no HTML elements. Pure ctx.fillRect, ctx.roundRect, ctx.fillText. The Architecture: Fully Decoupled tutorial.js is a 336-line standalone module — TutorialManager class. It imports nothing from the game engine. Zero coupling. // tutorial.js — NO engine imports export class TutorialManager { constructor(forceSpawnFn, canvasWidth, canvasHeight) { ... } start(playerX) { ... } dismiss() { ... } skip() { ... } checkCompletion(state) { ... } isSlowMode() { ... } hasActiveCard() { ... } getCurrentCard() { ... } } The engine's state is passed in as a snapshot from main.js each frame — tutorial.checkCompletion({ player, activeNaam, isNaamaJaapa, playerInTunnel }). The tutorial never reaches into the engine directly. Dependency injection for the spawn callback: // main.js const tutorial = new TutorialManager( (...args) => engine._forceSpawnMaya?.(...args), WIDTH, HEIGHT ); The tutorial says "I need a naama entity to appear here." The engine handles it. Neither module needs to know how the other works. The 5 Steps (Pañca-Dīkṣā) Each step has a id, shloka, shlokaCredit, task, hint, forceSpawn, and dismissToComplete flag: Step 1 — Move (Bhagavad Gita 6.5) उद्धरेदात्मनात्मानं नात्मानमवसादयेत्। Player learns to steer the chariot. Move ≥40px to complete. The soul must uplift itself — no one else can steer for you. Step 2 — Maya (Yogavasishtha) मायाजालमिदं विश्वं मोहयत्यखिलं जगत्। A naama entity is force-spawned at screen center. Player collects it. Recognising what is real (naam) vs illusion — the first step of awakening. Step 3 — Naam-Jaap (Ramcharitmanas) नाम जपत मंगल दिसि दसहूँ। Another naama force-spawned. Player presses SPACE to activate naam-jaap ring. The name protects in all ten directions — chant it. Step 4 — Tunnel (Bhagavad Gita 18.55) भक्त्या मामभिजानाति यावान्यश्चास्मि तत्त्वतः। Player enters the भक्ति-मार्ग (tunnel at screen center). Through devotion alone, the divine is truly known. Step 5 — Prarabdha (Skanda Purana) भोगेन क्षीयते पापं, तपसा क्षीयते मलः। An info card — no action required. The player learns that prarabdha (past-life karma) accumulates on rebirth and must be endured. Dismiss = tutorial complete. Slow-Motion Instead of Pause A key design decision: tutorial cards don't pause the game. They slow it. // gameLoop const dt = tutorial.isSlowMode() ? rawDt * 0.3 : rawDt; When a card is visible, time runs at 30% speed. The cosmos doesn't stop — it breathes slowly. Maya entities drift, the lotus-petal ring pulses, stars shimmer. The game world remains alive behind the card. This avoids a critical bug: using engine.isPaused for tutorial mode would break the audio system, gamepad polling, and timer logic. A dedicated slow-mode flag keeps concerns separated. Force-Spawn: Deterministic Maya Steps 2 and 3 need a naama entity to appear at a predictable position. Random spawning would make these steps non-deterministic — the player might wait too long or miss entirely. // karma.js — _forceSpawnMaya _forceSpawnMaya(type, x, y) { const sizeInfo = MAYA_SIZE_TABLE[type] || MAYA_SIZE_TABLE.default; for (let i = 0; i < this.mayaPool.length; i++) { if (!this.mayaPool[i].active) { this.mayaPool[i].active = true; this.mayaPool[i].x = x; this.mayaPool[i].y = y; this.mayaPool[i].width = sizeInfo.width; this.mayaPool[i].height = sizeInfo.height; this.mayaPool[i].type = type; break; } } } Pool-based — no push, no allocation. The entity falls naturally under mayaSpeed once spawned. Position is defined as canvas fractions in the step definition: forceSpawn: { type: 'naama', xRatio: 0.5, yRatio: 0.15 } // → Math.round(canvasWidth * 0.5), Math.round(canvasHeight * 0.15) Changing canvas size? The spawn position scales automatically. localStorage: One-Time Initiation The tutorial runs once per browser session, then marks itself complete: const TUTORIAL_STORAGE_KEY = 'moksha_tutorial_seen'; start(playerX) { if (localStorage.getItem(TUTORIAL_STORAGE_KEY) === '1') { this._done = true; return; } // ... begin tutorial } skip() { this._done = true; try { localStorage.setItem(TUTORIAL_STORAGE_KEY, '1'); } catch (_) {} } try/catch around localStorage — private browsing mode throws on setItem. Silent fail is correct here; the worst case is the tutorial shows again on next visit. ESC skips the tutorial at any point. The player chooses their own pace. Bugs Found Along the Way Building this surfaced three issues worth documenting: 1. Action keys fired during card display. SPACE, Q, F — all game actions — could trigger during a tutorial card. Naam-jaap would fire while the player was reading a shloka. Fix: block action dispatch when tutorial.hasActiveCard(). 2. engine.reset() didn't sync tutorial state. Pressing R (rebirth shortcut) reset the game but left the tutorial mid-step. Fix: call tutorial.start(engine.player.x) alongside engine.reset(). 3. Mobile ghost click dismissed the first card immediately. Tapping "Start Game" — after the start screen was removed — fired a delayed synthetic click on the canvas, instantly dismissing step 1. Fix: 600ms guard after game start before canvas click listener activates. What I Didn't Do No external tutorial library. No DOM overlays. No setTimeout chains. No "next button" state machine in the engine. The entire system is one file, one class, one clean public API. The engine doesn't know a tutorial exists. The tutorial doesn't know how the engine works. They talk through snapshots. That's the architecture मोक्ष runs on — modular, decoupled, Vedic at the core. What's Next The tutorial currently runs only on first play. A few things on the horizon: Language toggle — tutorial cards in English / Hindi (i18n system) Mobile layout — touch control integration with tutorial flow Gyroscope steering — for step 1, steering the chariot with device tilt Play मोक्ष: weirdcodes.itch.io/moksha GitHub: github.com/weirdcodesofficial/MOKSHA Human-designed, AI-assisted. Spiritual design, gameplay vision, and all Vedic decisions — Weired Codes. Code assistance — Claude by Anthropic.
This is a summary aggregated from Dev.to. Read the complete article on the original site:
Read full article at Dev.to