diff --git a/audio/chetanaJaagrita.mp3 b/audio/chetanaaJaagrita.mp3 similarity index 100% rename from audio/chetanaJaagrita.mp3 rename to audio/chetanaaJaagrita.mp3 diff --git a/audio/drishti.mp3 b/audio/drishtee.mp3 similarity index 100% rename from audio/drishti.mp3 rename to audio/drishtee.mp3 diff --git a/audio/jagritaBreath.mp3 b/audio/jagritaBreath.mp3 deleted file mode 100644 index fc88bf4..0000000 Binary files a/audio/jagritaBreath.mp3 and /dev/null differ diff --git a/audio/purnaSamarpana.mp3 b/audio/poornaSamarpana.mp3 similarity index 100% rename from audio/purnaSamarpana.mp3 rename to audio/poornaSamarpana.mp3 diff --git a/audio/prarabdhaBandhana.mp3 b/audio/praarabdhaBandhana.mp3 similarity index 100% rename from audio/prarabdhaBandhana.mp3 rename to audio/praarabdhaBandhana.mp3 diff --git a/audio/prarambha.mp3 b/audio/praarambha.mp3 similarity index 100% rename from audio/prarambha.mp3 rename to audio/praarambha.mp3 diff --git a/index.html b/index.html index 5cd5249..3e5b50b 100644 --- a/index.html +++ b/index.html @@ -11,7 +11,7 @@ - + @@ -19,7 +19,7 @@ - +
🌿 0
🥀 0
-
📜 0
+
📜 0
@@ -62,7 +62,7 @@
♻️ 0
😴
☀️
-
🤲
+
🤲
@@ -106,7 +106,7 @@ - +
🛠️
@@ -135,6 +135,16 @@ style="font-family:'Rajdhani',sans-serif;font-size:15px;line-height:1.8;color:rgba(255,255,255,0.55);max-width:80%;font-weight:500;">

'R' दबाएं जीवन रथ को पुनः आरंभ करने के लिए

+ + @@ -147,29 +157,29 @@

॥ स्तम्भन ॥

- -
-
- -
+ +
+
+ +

॥ शास्त्र ॥

रथ का ज्ञान

-
- -
-
-
-
- - -
+
+
diff --git a/src/audio.js b/src/audio.js index 70a9642..322dbea 100644 --- a/src/audio.js +++ b/src/audio.js @@ -19,7 +19,7 @@ * ── बाहरी निर्भरताएँ (injected callbacks) ───────────────── * Audio.setGameStateGetter(fn) * fn() → { isGameStarted, gameOver, won, isPaused, - * isShastraVisible, chetanaaJaagrita } + * isShaashtraVisible, chetanaaJaagrita } * * Audio.setVibrateCallback(fn) * fn(weakMagnitude, strongMagnitude, duration) → void @@ -32,7 +32,7 @@ * // पेज-लोड पर एक बार: * Audio.setGameStateGetter(() => ({ * isGameStarted, gameOver, won, isPaused, - * isShastraVisible, chetanaaJaagrita + * isShaashtraVisible, chetanaaJaagrita * })); * Audio.setVibrateCallback(vibrateGamepad); * Audio.setReadinessGetters({ @@ -98,11 +98,11 @@ const SUSHUPTI_SWAANSA_DUCK_REDUCTION = 0.20; * हल्के SFX कम। */ const DUCK_STRENGTH = new Map([ - ['purnaSamarpana', 0.60], - ['drishti', 0.35], + ['poornaSamarpana', 0.60], + ['drishtee', 0.35], ['andhakaara', 0.40], ['shuvha', 0.50], - ['ashuvha', 0.55], + ['ashuvha', 0.55], ['jaapa', 0.55], ['samarpita', 0.45], ['naamaSamarpita', 0.55], @@ -120,7 +120,7 @@ const DUCK_STRENGTH = new Map([ ['punyaBandhana', 0.40], ['bandhanaMukta', 0.35], ['naama', 0.45], - ['antimaCharana', 0.35], + ['antimaCharana', 0.35], ['kripa', 0.50], ['shankhaDhwani', 0.45], ['jyotiDhwani', 0.40], @@ -179,12 +179,12 @@ class AudioManager { jyotiDhwani: null, // B-press ज्योति shankhaPrapta: null, // शंख-संग्रह jyotiPrapta: null, // ज्योति-संग्रह - purnaSamarpana: null, // पूर्ण-समर्पण - drishti: null, // दृष्टि लौटी + poornaSamarpana: null, // पूर्ण-समर्पण + drishtee: null, // दृष्टि लौटी andhakaara: null, // पाप-अंधकार // Batch-2 (deferred — भारी / देर से ज़रूरी) bgMusic: null, // पृष्ठभूमि संगीत (~6.5MB) - chetanaJaagrita: null, // चेतना-जागृति + chetanaaJaagrita: null, // चेतना-जागृति pralaya: null, // प्रलय jaagritaSwaansa: null, // अंतरिक्ष-श्वास (ambient loop) moksha: null, // मोक्ष-विजय @@ -244,7 +244,7 @@ class AudioManager { // ── Injected callbacks ────────────────────────────── /** * () => { isGameStarted, gameOver, won, isPaused, - * isShastraVisible, chetanaaJaagrita } + * isShaashtraVisible, chetanaaJaagrita } */ this._getGameState = null; @@ -268,7 +268,7 @@ class AudioManager { * circular dependency को callback pattern से हल करता है। * * @param {Function} fn — () => { isGameStarted, gameOver, won, - * isPaused, isShastraVisible, chetanaaJaagrita } + * isPaused, isShaashtraVisible, chetanaaJaagrita } */ setGameStateGetter(fn) { this._getGameState = fn; @@ -455,19 +455,19 @@ class AudioManager { this._vibrate?.(0.10, 0.05, 50); break; - case 'purnaSamarpana': + case 'poornaSamarpana': // अंतिम चरण में समस्त नाम-समर्पण (एक बार/जीवन-चक्र) - buf.purnaSamarpana - ? this._playBufferedSound(buf.purnaSamarpana, ctx.destination, 0.65) + buf.poornaSamarpana + ? this._playBufferedSound(buf.poornaSamarpana, ctx.destination, 0.65) : this._playTone(987.77, 0.14, 'sine', 0.04, 1567.98); this._vibrate?.(0.20, 0.25, 130); break; // ── दृष्टि / अंधकार ──────────────────────────── - case 'drishti': + case 'drishtee': // पाप-अंधकार (ashuvhaKarma≥3) से बाहर आने पर - buf.drishti - ? this._playBufferedSound(buf.drishti, ctx.destination, 0.55) + buf.drishtee + ? this._playBufferedSound(buf.drishtee, ctx.destination, 0.55) : this._playTone(880, 0.10, 'sine', 0.03, 1318.51); this._vibrate?.(0.10, 0.08, 60); break; @@ -627,10 +627,10 @@ class AudioManager { // ── चेतना-जागृति (fade-in envelope) ──────────── case 'chetana': // समर्पित≥50 पर एक बार — पूरी buffer-duration तक प्राकृतिक रूप से बजे - if (buf.chetanaJaagrita) { + if (buf.chetanaaJaagrita) { const cNow = ctx.currentTime; const cSrc = ctx.createBufferSource(); - cSrc.buffer = buf.chetanaJaagrita; + cSrc.buffer = buf.chetanaaJaagrita; const cGain = ctx.createGain(); cGain.gain.setValueAtTime(0.0001, cNow); cGain.gain.exponentialRampToValueAtTime(0.7, cNow + 0.05); // हल्का fade-in @@ -639,7 +639,7 @@ class AudioManager { cSrc.start(cNow); // premature stop() नहीं — पूरी duration तक बजे (शास्त्र-संगत) } else { - console.warn('⚠️ chetanaJaagrita.mp3 लोड नहीं हुई — ./audio/chetanaJaagrita.mp3 path जाँचें'); + console.warn('⚠️ chetanaaJaagrita.mp3 लोड नहीं हुई — ./audio/chetanaaJaagrita.mp3 path जाँचें'); } break; @@ -774,7 +774,7 @@ class AudioManager { } // ── jaagritaSwaansa — gameplay-gated, सांस-सिंक ── - // 🛠️ बग-फिक्स: पहले pause/shastra/pralaya/moksha में भी बजती थी + // 🛠️ बग-फिक्स: पहले pause/shaashtra/pralaya/moksha में भी बजती थी if (this._jaagritaSwaansaGain) { const swaansaVol = JAAGRITA_SWAANSA_VOLUME * (1 - BG_SWAANSA_MOD_RANGE + bp * BG_SWAANSA_MOD_RANGE); @@ -783,7 +783,7 @@ class AudioManager { } // ── sushuptiSwaansa — gameplay-gated, सांस-सिंक (pre-chetanaaJaagrita) ── - // 🛠️ बग-फिक्स: shathendriya जैसा gameplay-gating — pause/shastra पर मौन + // 🛠️ बग-फिक्स: shathendriya जैसा gameplay-gating — pause/shaashtra पर मौन if (this._sushuptiSwaansaGain) { const dreamVol = SUSHUPTI_SWAANSA_VOLUME * (1 - BG_SWAANSA_MOD_RANGE + bp * BG_SWAANSA_MOD_RANGE); @@ -827,7 +827,7 @@ class AudioManager { } /** - * punahaPrarambha() में बुलाएँ — jaagritaSwaansa बंद करें। + * punahaPraarambha() में बुलाएँ — jaagritaSwaansa बंद करें। * अगले जीवन में chetanaaJaagrita होने पर दोबारा शुरू होगी। * (replaces stopJaagritaSwaansaLayer()) */ @@ -842,8 +842,8 @@ class AudioManager { } /** - * punahaPrarambha() में बुलाएँ — नए जीवन-चक्र के लिए sushuptiSwaansa फिर शुरू। - * (replaces startSushuptiSwaansaLayer() public call in punahaPrarambha) + * punahaPraarambha() में बुलाएँ — नए जीवन-चक्र के लिए sushuptiSwaansa फिर शुरू। + * (replaces startSushuptiSwaansaLayer() public call in punahaPraarambha) */ startJaagritaSwaansaLayer() { @@ -883,7 +883,7 @@ class AudioManager { _isActiveGameplay() { const s = this._getGameState?.(); if (!s) return false; - return s.isGameStarted && !s.gameOver && !s.won && !s.isPaused && !s.isShastraVisible; + return s.isGameStarted && !s.gameOver && !s.won && !s.isPaused && !s.isShaashtraVisible; } // ── Synth / buffer playback ───────────────────────────── @@ -1047,7 +1047,7 @@ class AudioManager { { url: './audio/shathendriya.mp3', key: 'shathendriya'}, { url: './audio/sushuptiSwaansa.mp3', key: 'sushuptiSwaansa'}, { url: './audio/timer.mp3', key: 'timer'}, - { url: './audio/prarabdhaBandhana.mp3', key: 'prarabdhaBandhana'}, + { url: './audio/praarabdhaBandhana.mp3', key: 'prarabdhaBandhana'}, { url: './audio/paapaBandhana.mp3', key: 'paapaBandhana'}, { url: './audio/punyaBandhana.mp3', key: 'punyaBandhana'}, { url: './audio/bandhanaMukta.mp3', key: 'bandhanaMukta'}, @@ -1059,9 +1059,9 @@ class AudioManager { { url: './audio/shankhaDhwani.mp3', key: 'shankhaDhwani'}, { url: './audio/jyotiDhwani.mp3', key: 'jyotiDhwani'}, { url: './audio/jyotiPrapta.mp3', key: 'jyotiPrapta'}, - { url: './audio/drishti.mp3', key: 'drishti'}, + { url: './audio/drishtee.mp3', key: 'drishtee'}, { url: './audio/shankhaPrapta.mp3', key: 'shankhaPrapta'}, - { url: './audio/purnaSamarpana.mp3', key: 'purnaSamarpana'}, + { url: './audio/poornaSamarpana.mp3', key: 'poornaSamarpana'}, { url: './audio/andhakaara.mp3', key: 'andhakaara'} ]; @@ -1107,7 +1107,7 @@ class AudioManager { }; const [bg, chetana, pralaya, jaagritaSwaansa, moksha, antimaCharana] = await Promise.all([ _loadAmbient('./audio/bgMusic.mp3'), - _loadAmbient('./audio/chetanaJaagrita.mp3'), + _loadAmbient('./audio/chetanaaJaagrita.mp3'), _loadAmbient('./audio/pralaya.mp3'), _loadAmbient('./audio/jaagritaSwaansa.mp3'), _loadAmbient('./audio/moksha.mp3'), @@ -1116,7 +1116,7 @@ class AudioManager { Object.assign(this.audioBuffers, { bgMusic: bg, - chetanaJaagrita: chetana, + chetanaaJaagrita: chetana, pralaya, jaagritaSwaansa, moksha, @@ -1230,7 +1230,7 @@ class AudioManager { this._jaagritaSwaansaGain = this.audioCtx.createGain(); // 🛠️ बग-फिक्स: node बनने के तुरंत बाद isActiveGameplay() check — - // ताकि pause/shastra के दौरान node बनते ही पूर्ण-स्तर gain न मिले + // ताकि pause/shaashtra के दौरान node बनते ही पूर्ण-स्तर gain न मिले const initVol = this._isActiveGameplay() ? JAAGRITA_SWAANSA_VOLUME : 0; this._jaagritaSwaansaGain.gain.setValueAtTime(initVol, now); this._jaagritaSwaansaGain.connect(this._bgMasterGain); diff --git a/src/engine.js b/src/engine.js index 5048535..fc2b471 100644 --- a/src/engine.js +++ b/src/engine.js @@ -121,21 +121,21 @@ export class KarmaEngine { this.shuvhaKarma = 0; // पुण्य (सक्रिय) this.ashuvhaKarma = 0; // पाप (सक्रिय) this.activeNaam = 0; // ॐ नाम (उपयोग-योग्य) - this.prarabdha = 0; // प्रारब्ध (संचित — सिर्फ़ 10-नाम से भस्म) - this.prarabdhaTimer = 0; // भोग-countdown (frames); पुनर्जन्म पर persist, R-reset पर शून्य - this.prarabdhaGatiModifier = 1.0; // पूर्व-जन्म के punya×paap का संचित गति-भार + this.praarabdha = 0; // प्रारब्ध (संचित — सिर्फ़ 10-नाम से भस्म) + this.praarabdhaTimer = 0; // भोग-countdown (frames); पुनर्जन्म पर persist, R-reset पर शून्य + this.praarabdhaGatiModifier = 1.0; // पूर्व-जन्म के punya×paap का संचित गति-भार this._currentGatiModifier = 1.0; // इस जन्म का live ashuvha×shuvha modifier (rebirth पर snapshot) persist, R-reset पर शून्य - this._prarabdhaTimerPulseAccum = 0; // orbit pulse accumulator + this._praarabdhaTimerPulseAccum = 0; // orbit pulse accumulator this.samarpita = 0; // समर्पित (lifetime) this.punaraJanmaCount = 0; // पुनर्जन्म गिनती - this.isKarmaImmune = false; // purnaSamarpana के बाद अस्थायी कर्म-रक्षा + this.isKarmaImmune = false; // poornaSamarpana के बाद अस्थायी कर्म-रक्षा this.kripa = 0; // कृपा (अनुग्रह) this.shankha = 0; // शंख resource this.jyoti = 0; // ज्योति resource // ── Spiritual State ────────────────────────────────── this.chetanaaJaagrita = false; // मोक्ष की प्रामाणिक शर्त - this.purnaSamarpana = false; // अंतिम-चरण में समस्त नाम समर्पित + this.poornaSamarpana = false; // अंतिम-चरण में समस्त नाम समर्पित this.jaapaNaama = "राधा"; // नाम-जाप पर floating text this.isNaamaJaapa = false; // क्या अभी नाम-जाप-वलय सक्रिय है? this.naamaGhera = 0; // नाम-जाप-वलय की वर्तमान त्रिज्या @@ -151,8 +151,8 @@ export class KarmaEngine { this.gameOver = false; this.isPaused = false; this.won = false; - this.isShastraVisible = false; - this.wasAlreadyPaused = false; // shastra खुलने से पहले का pause-state + this.isShaashtraVisible = false; + this.wasAlreadyPaused = false; // shaashtra खुलने से पहले का pause-state // ── Visual / Animation State ───────────────────────── this.smoothSize = 60; // player body-size (lerped) @@ -225,8 +225,8 @@ export class KarmaEngine { // ── Audio/sound edge-detection flags ───────────────── this._prevGoodKarmaForSound = 0; this._prevBadKarmaForSound = 0; - this._prevPrarabdhaForSound = 0; - this._prevPurnaSamarpana = false; + this._prevPraarabdhaForSound = 0; + this._prevPoornaSamarpana = false; this._prevDrishtiClear = true; this._prevPulledHorseIndex = -1; this._mayaConsumedWhilePulling = false; @@ -240,7 +240,7 @@ export class KarmaEngine { // ── Timer sound flags ──────────────────────────────── this._timerSoundPlayed = false; this._timerTickAccumulator = 0; - this._lastPrarabdhaAlertSecond = -1; + this._lastPraarabdhaAlertSecond = -1; // ── Contextual alert edge-detection (Issue #9) ─────── this._prevSamaya200 = false; // samaya < 200 one-shot warning @@ -250,15 +250,15 @@ export class KarmaEngine { this._samarpitaMilestones = new Set(); // milestone tracking: 10, 25, 50 // ── HUD animation state ────────────────────────────── - this._oldStats = { naama:-1, punya:-1, paap:-1, prarabdha:-1, samarpita:-1, + this._oldStats = { naama:-1, punya:-1, paap:-1, praarabdha:-1, samarpita:-1, punaraJanma:-1, gatee:"-1", kripa:-1, chetana:"", - shankha:-1, drishti:"", purnaSamarpana:"", jyoti:-1 }; - this._uiScales = { naama:1, punya:1, paap:1, prarabdha:1, samarpita:1, + shankha:-1, drishti:"", poornaSamarpana:"", jyoti:-1 }; + this._uiScales = { naama:1, punya:1, paap:1, praarabdha:1, samarpita:1, punaraJanma:1, gatee:1, kripa:1, chetana:1, - shankha:1, drishti:1, purnaSamarpana:1, jyoti:1 }; - this._uiGlows = { naama:0, punya:0, paap:0, prarabdha:0, samarpita:0, + shankha:1, drishti:1, poornaSamarpana:1, jyoti:1 }; + this._uiGlows = { naama:0, punya:0, paap:0, praarabdha:0, samarpita:0, punaraJanma:0, gatee:0, kripa:0, chetana:0, - shankha:0, drishti:0, purnaSamarpana:0, jyoti:0 }; + shankha:0, drishti:0, poornaSamarpana:0, jyoti:0 }; // ── Alert Queue System (Issue #10) ─────────────────── /** Canvas alert queue — max 4 active cards */ @@ -291,11 +291,11 @@ export class KarmaEngine { /** * DOM element references inject करें। - * @param {Object} UI — { naama, punya, paap, prarabdha, samarpita, + * @param {Object} UI — { naama, punya, paap, praarabdha, samarpita, * punaraJanma, kripa, shankha, jyoti, drishti, - * purnaSamarpana, chetana, samayaVal, swaansaVal, + * poornaSamarpana, chetana, samayaVal, swaansaVal, * gatee, alertBox, overlay, overlayTitle, - * overlaySubtitle, viraamaOverlay, shastraOverlay, + * overlaySubtitle, viraamaOverlay, shaashtraOverlay, * container } */ setUI(UI) { @@ -374,7 +374,7 @@ export class KarmaEngine { * @param {number} frameNow — performance.now() timestamp */ update(dt, keys, frameNow) { - if (this.gameOver || this.isPaused || this.isShastraVisible) return; + if (this.gameOver || this.isPaused || this.isShaashtraVisible) return; // ── 1. Outer-orbit counts sync (karma.js) ──────────── this._syncOrbitCounts(); @@ -404,11 +404,11 @@ export class KarmaEngine { this._prevGoodKarmaForSound = this.shuvhaKarma; this._prevBadKarmaForSound = this.ashuvhaKarma; - if (this.prarabdha > 0 && this._prevPrarabdhaForSound === 0) - this._cb.playSound?.('prarabdhaBandhana'); - if (this.prarabdha === 0 && this._prevPrarabdhaForSound > 0) + if (this.praarabdha > 0 && this._prevPraarabdhaForSound === 0) + this._cb.playSound?.('praarabdhaBandhana'); + if (this.praarabdha === 0 && this._prevPraarabdhaForSound > 0) this._cb.playSound?.('bandhanaMukta'); - this._prevPrarabdhaForSound = this.prarabdha; + this._prevPraarabdhaForSound = this.praarabdha; // ── 5. कृपा-माइलस्टोन edge-detection ──────────────── if (this.activeNaam > this._prevActiveNaamForKripa) @@ -432,12 +432,12 @@ export class KarmaEngine { } // ── 6. पूर्ण-समर्पण edge-detection ────────────────── - if (this.purnaSamarpana && !this._prevPurnaSamarpana) { - this._cb.playSound?.('purnaSamarpana'); + if (this.poornaSamarpana && !this._prevPoornaSamarpana) { + this._cb.playSound?.('poornaSamarpana'); this._addFloatingText("🙌", "#ffe9a8", { alpha:1.5, vy:-3, isBigName:true }); } - this._prevPurnaSamarpana = this.purnaSamarpana; + this._prevPoornaSamarpana = this.poornaSamarpana; // ── 7. दृष्टि/अंधकार edge-detection ───────────────── const isDrishtiClear = this.ashuvhaKarma < 3; @@ -659,7 +659,7 @@ export class KarmaEngine { // वलय पूर्ण — नाम-शक्ति जाँचें // ⚠️ शास्त्र-संगत (Issue #11): प्रारब्ध नाम-जाप से नष्ट नहीं होता। - // activeNaam >= 10 होने पर prarabdhaTimer 2× गति से घटता है (§22.5)। + // activeNaam >= 10 होने पर praarabdhaTimer 2× गति से घटता है (§22.5)। if (this.naamaGhera > NAAMA_JAAP_MAX_RADIUS) { this.isNaamaJaapa = false; this.naamaGhera = 0; this._alertKey('naamaJapa', '🌿', 'achievement'); @@ -715,16 +715,16 @@ export class KarmaEngine { // इस frame का combined modifier — rebirth पर snapshot हेतु store this._currentGatiModifier = ashuvhaTimeModifier * shuvhaTimeModifier; // प्रारब्ध-modifier = पूर्व-जन्मों के punya×paap का संचित भार - const prarabdhaModifier = this.prarabdha > 0 ? this.prarabdhaGatiModifier : 1.0; + const praarabdhaModifier = this.praarabdha > 0 ? this.praarabdhaGatiModifier : 1.0; if (!this.swaansaSamapta) { // ── Bug 6 fix: प्रारब्ध का ×1.15 samaya penalty (शास्त्र-संगत) ── - // prarabdha=0 → 1.0×; prarabdha=1 → 1.15×; prarabdha=5 → ≈2.01× - // cap: MAX 3.0× (prarabdha≈9 से ऊपर) — game over न हो instantly - const prarabdhaSamayaMul = this.prarabdha > 0 - ? Math.min(3.0, Math.pow(1.15, this.prarabdha)) + // praarabdha=0 → 1.0×; praarabdha=1 → 1.15×; praarabdha=5 → ≈2.01× + // cap: MAX 3.0× (praarabdha≈9 से ऊपर) — game over न हो instantly + const praarabdhaSamayaMul = this.praarabdha > 0 + ? Math.min(3.0, Math.pow(1.15, this.praarabdha)) : 1.0; - this.samaya -= 0.8 * ashuvhaTimeModifier * shuvhaTimeModifier * prarabdhaSamayaMul * dt; this.swaansaTimer += dt; + this.samaya -= 0.8 * ashuvhaTimeModifier * shuvhaTimeModifier * praarabdhaSamayaMul * dt; this.swaansaTimer += dt; if (this.swaansaTimer >= 360) { this.swaansaTimer -= 360; if (this.swaansa > 0) this.swaansa--; @@ -738,7 +738,7 @@ export class KarmaEngine { if (this._UI?.swaansaVal?.innerText !== swaansaDisplay && this._UI?.swaansaVal) this._UI.swaansaVal.innerText = swaansaDisplay; - const currentWarpVal = (ashuvhaTimeModifier * shuvhaTimeModifier * prarabdhaModifier * 100).toFixed(0); this._updateStatWithPulse(this._UI?.gatee, 'gatee', currentWarpVal, '⚡', '%'); + const currentWarpVal = (ashuvhaTimeModifier * shuvhaTimeModifier * praarabdhaModifier * 100).toFixed(0); this._updateStatWithPulse(this._UI?.gatee, 'gatee', currentWarpVal, '⚡', '%'); if (this.samaya <= 0) { this.samaya = 0; this.swaansa = 0; this.swaansaSamapta = true; @@ -769,13 +769,13 @@ export class KarmaEngine { // ── 18. Stars & sparkles movement ───────────────────── this.stars.forEach(star => { if (!this.swaansaSamapta) { - star.y += star.speed * (ashuvhaTimeModifier * shuvhaTimeModifier * prarabdhaModifier + 0.1) * dt; + star.y += star.speed * (ashuvhaTimeModifier * shuvhaTimeModifier * praarabdhaModifier + 0.1) * dt; if (star.y > this.HEIGHT) { star.y = this.HUD_TOP_Y; star.x = Math.random() * this.WIDTH; } } }); this.tunnelSparkles.forEach(sparkle => { if (!this.swaansaSamapta) { - sparkle.y -= sparkle.speed * (ashuvhaTimeModifier * shuvhaTimeModifier * prarabdhaModifier + 0.2) * dt; sparkle.alpha += sparkle.fadeSpeed * dt; + sparkle.y -= sparkle.speed * (ashuvhaTimeModifier * shuvhaTimeModifier * praarabdhaModifier + 0.2) * dt; sparkle.alpha += sparkle.fadeSpeed * dt; if (sparkle.alpha > 0.9 || sparkle.alpha < 0.2) sparkle.fadeSpeed = -sparkle.fadeSpeed; if (sparkle.y < 0) { sparkle.y = this.HEIGHT; @@ -842,24 +842,24 @@ export class KarmaEngine { if (this.outerOrbits[2]?.glowTimer > 0) this.outerOrbits[2].glowTimer -= dt; // ── 22.5. प्रारब्ध-भोग countdown — "प्रारब्धं भुज्यते एव" (Issue #11) ─ - if (this.prarabdhaTimer > 0) { + if (this.praarabdhaTimer > 0) { // orbit pulse — हर second 📜 हल्की चमके - this._prarabdhaTimerPulseAccum += dt; - if (this._prarabdhaTimerPulseAccum >= 60) { - this._prarabdhaTimerPulseAccum -= 60; + this._praarabdhaTimerPulseAccum += dt; + if (this._praarabdhaTimerPulseAccum >= 60) { + this._praarabdhaTimerPulseAccum -= 60; if (this.outerOrbits[2]) this.outerOrbits[2].glowTimer = 18; } - // ── prarabdha unit घटाने का logic ── - const prevPrarabdha = this.prarabdha; - // Bhog penalty: prarabdha endure करते समय samaya थोड़ा तेज़ घटे - this.prarabdhaTimer = Math.max(0, this.prarabdhaTimer - dt); - const newPrarabdha = this.prarabdhaTimer > 0 - ? Math.ceil(this.prarabdhaTimer / PRARABDHA_BHOG_FRAMES) : 0; + // ── praarabdha unit घटाने का logic ── + const prevPraarabdha = this.praarabdha; + // Bhog penalty: praarabdha endure करते समय samaya थोड़ा तेज़ घटे + this.praarabdhaTimer = Math.max(0, this.praarabdhaTimer - dt); + const newPraarabdha = this.praarabdhaTimer > 0 + ? Math.ceil(this.praarabdhaTimer / PRARABDHA_BHOG_FRAMES) : 0; - if (newPrarabdha < prevPrarabdha) { - this.prarabdha = newPrarabdha; - if (this.prarabdha > 0) { + if (newPraarabdha < prevPraarabdha) { + this.praarabdha = newPraarabdha; + if (this.praarabdha > 0) { // ── unit घटा — explosion + alert (alert flooding नहीं, unit-change पर ही) ── this._createExplosion( this.player.x + this.player.width / 2, @@ -867,18 +867,18 @@ export class KarmaEngine { "#a78bfa" ); this._addFloatingText("-📜", "#a78bfa", { vy: -2.5, isBigName: true }); - this._alertKey('prarabdhaBhoga', '📜', 'info', { n: this.prarabdha }); + this._alertKey('praarabdhaBhoga', '📜', 'info', { n: this.praarabdha }); this._cb.playSound?.('bandhanaMukta'); } else { // ── पूर्ण मुक्ति ── - this.prarabdhaTimer = 0; + this.praarabdhaTimer = 0; this._createExplosion( this.player.x + this.player.width / 2, this.player.y + this.player.height / 2, "#e879f9" ); - this._addFloatingText(t('notify.prarabdhaMukta'), "#e879f9", { vy: -2.8, isBigName: true }); - this._alertKey('prarabdhaMukta', '📜', 'achievement'); + this._addFloatingText(t('notify.praarabdhaMukta'), "#e879f9", { vy: -2.8, isBigName: true }); + this._alertKey('praarabdhaMukta', '📜', 'achievement'); this._cb.playSound?.('bandhanaMukta'); this._triggerGlow("#e879f9"); } @@ -920,17 +920,17 @@ export class KarmaEngine { /** * शास्त्र overlay toggle। - * main.js से toggleShastra() में बुलाएँ। + * main.js से toggleShaashtra() में बुलाएँ। */ - toggleShastra() { + toggleShaashtra() { if (this._UI?.viraamaOverlay?.style.display === 'flex') { this._UI.viraamaOverlay.style.display = 'none'; } - this.isShastraVisible = !this.isShastraVisible; - if (this._UI?.shastraOverlay) { - this._UI.shastraOverlay.style.display = this.isShastraVisible ? 'flex' : 'none'; + this.isShaashtraVisible = !this.isShaashtraVisible; + if (this._UI?.shaashtraOverlay) { + this._UI.shaashtraOverlay.style.display = this.isShaashtraVisible ? 'flex' : 'none'; } - if (this.isShastraVisible) { + if (this.isShaashtraVisible) { this.wasAlreadyPaused = this.isPaused; this.isPaused = true; this._cb.playSound?.('viraama'); @@ -966,6 +966,8 @@ export class KarmaEngine { `${t('end.punarjanmaLabel')} ` + `${this.punaraJanmaCount}`; if (reason === "FORCE STOPPED") { + // प्रलय — पुनर्जन्म बटन दिखाएँ + if (this._UI?.punarjanmaBtn) this._UI.punarjanmaBtn.style.display = 'inline-block'; if (this._UI?.overlayTitle) { this._UI.overlayTitle.innerText = t('end.pralaya.title'); this._UI.overlayTitle.style.fontFamily = "'Noto Sans Devanagari', sans-serif"; @@ -980,11 +982,10 @@ export class KarmaEngine { COUNT_HTML + CREDIT; } } else if (this.won) { + // मोक्ष — पुनर्जन्म शास्त्र-विरुद्ध; बटन छिपाएँ + if (this._UI?.punarjanmaBtn) this._UI.punarjanmaBtn.style.display = 'none'; if (this._UI?.overlayTitle) { this._UI.overlayTitle.innerText = t('end.moksha.title'); - // ⚠️ BUG FIX: प्रलय शाखा fontFamily बदलती है, पर यह शाखा उसे - // कभी रीसेट नहीं करती थी — प्रलय के बाद मोक्ष देखने पर - // शीर्षक ग़लत font में रह जाता था। अब स्पष्ट रूप से सेट। this._UI.overlayTitle.style.fontFamily = "'Noto Sans Devanagari', sans-serif"; this._UI.overlayTitle.style.color = "#ffffff"; } @@ -1004,6 +1005,8 @@ export class KarmaEngine { } this._cb.playSound?.('vijaya'); } else { + // संसार-पुनर्जन्म — पुनर्जन्म बटन दिखाएँ + if (this._UI?.punarjanmaBtn) this._UI.punarjanmaBtn.style.display = 'inline-block'; if (this._UI?.overlayTitle) { this._UI.overlayTitle.innerText = t('end.rebirth.title'); this._UI.overlayTitle.style.fontFamily = "'Noto Sans Devanagari', sans-serif"; @@ -1021,12 +1024,12 @@ export class KarmaEngine { } /** - * punahaPrarambha (R-key / restart-btn) — सम्पूर्ण reset। + * punahaPraarambha (R-key / restart-btn) — सम्पूर्ण reset। */ reset() { // ── Karma reset ── - this.prarabdha = 0; this.prarabdhaTimer = 0; this.shuvhaKarma = 0; this.ashuvhaKarma = 0; - this.prarabdhaGatiModifier = 1.0; this._currentGatiModifier = 1.0; this.activeNaam = 0; this.samarpita = 0; this.punaraJanmaCount = 0; + this.praarabdha = 0; this.praarabdhaTimer = 0; this.shuvhaKarma = 0; this.ashuvhaKarma = 0; + this.praarabdhaGatiModifier = 1.0; this._currentGatiModifier = 1.0; this.activeNaam = 0; this.samarpita = 0; this.punaraJanmaCount = 0; this.isKarmaImmune = false; this.kripa = 0; this.shankha = 0; this.jyoti = 0; // ── Alert queue reset ── this.alertQueue = []; this._nextAlertId = 0; @@ -1037,19 +1040,19 @@ export class KarmaEngine { if (this._UI?.swaansaVal) this._UI.swaansaVal.innerText = `10`; // ── Spiritual state reset ── - this.chetanaaJaagrita = false; this.purnaSamarpana = false; + this.chetanaaJaagrita = false; this.poornaSamarpana = false; // ── Edge-detection flags reset ── - this._prevPurnaSamarpana = false; this._prevDrishtiClear = true; + this._prevPoornaSamarpana = false; this._prevDrishtiClear = true; this._prevGoodKarmaForSound = 0; this._prevBadKarmaForSound = 0; - this._prevPrarabdhaForSound = 0; + this._prevPraarabdhaForSound = 0; this._prevActiveNaamForKripa = 0; this._prevSamarpitaForKripa = 0; this._naamaSinceLastKripa = 0; this._samarpitaSinceLastKripa = 0; this._prevPulledHorseIndex = -1; this._mayaConsumedWhilePulling = false; // ── Timer flags reset ── this._timerSoundPlayed = false; this._timerTickAccumulator = 0; - this._lastPrarabdhaAlertSecond = -1; + this._lastPraarabdhaAlertSecond = -1; // ── Contextual alert flags reset (Issue #9) ── this._prevSamaya200 = false; @@ -1082,8 +1085,8 @@ export class KarmaEngine { this._cb.startSushuptiSwaansaLayer?.(); // ── HUD cache invalidate ── - this._oldStats = { purnaSamarpana:"", naama:-1, punya:-1, paap:-1, - prarabdha:-1, samarpita:-1, punaraJanma:-1, + this._oldStats = { poornaSamarpana:"", naama:-1, punya:-1, paap:-1, + praarabdha:-1, samarpita:-1, punaraJanma:-1, gatee:"-1", kripa:-1, chetana:"", shankha:-1, drishti:"", jyoti:-1 }; // ── UI reset ── @@ -1113,8 +1116,8 @@ export class KarmaEngine { shuvhaKarma: this.shuvhaKarma, ashuvhaKarma: this.ashuvhaKarma, activeNaam: this.activeNaam, - prarabdha: this.prarabdha, - prarabdhaTimer: this.prarabdhaTimer, + praarabdha: this.praarabdha, + praarabdhaTimer: this.praarabdhaTimer, samarpita: this.samarpita, punaraJanmaCount: this.punaraJanmaCount, kripa: this.kripa, @@ -1122,7 +1125,7 @@ export class KarmaEngine { jyoti: this.jyoti, // Spiritual chetanaaJaagrita: this.chetanaaJaagrita, - purnaSamarpana: this.purnaSamarpana, + poornaSamarpana: this.poornaSamarpana, // Time samaya: this.samaya, swaansa: this.swaansa, @@ -1132,7 +1135,7 @@ export class KarmaEngine { gameOver: this.gameOver, isPaused: this.isPaused, won: this.won, - isShastraVisible: this.isShastraVisible, + isShaashtraVisible: this.isShaashtraVisible, // Visual player: this.player, smoothSize: this.smoothSize, diff --git a/src/i18n.js b/src/i18n.js index 1286841..e43c53b 100644 --- a/src/i18n.js +++ b/src/i18n.js @@ -16,8 +16,8 @@ const STRINGS = { 'viraama.resume': 'जारी रखें', 'viraama.restart': 'पुनः आरंभ', 'viraama.quit': 'छोड़ें', - 'shastra.title': '॥ शास्त्र ॥', - 'shastra.subtitle':'रथ का ज्ञान', + 'shaashtra.title': '॥ शास्त्र ॥', + 'shaashtra.subtitle':'रथ का ज्ञान', 'tutorial.dismiss':'ENTER / TAP to continue', 'loading.text': 'रथ तैयार हो रहा है...', 'alert.samaya200.title': 'समय समाप्त होने वाला है', @@ -38,12 +38,12 @@ const STRINGS = { 'alert.chakravaataShankha.subtitle': 'Y दबाएँ — शंख-ध्वनि से नष्ट करें!', 'alert.chakravaataNone.subtitle': 'शंख संग्रह करें — अभी सुरक्षा नहीं।', 'alert.drishti.title': 'दृष्टि अवरुद्ध', - 'alert.drishtiJyoti.subtitle': 'B दबाएँ — ज्योति से अंधकार भगाएँ।', + 'alert.drishtiVisionb.subtitle': 'B दबाएँ — ज्योति से अंधकार भगाएँ।', 'alert.drishtiNone.subtitle': 'ज्योति संग्रह करें — पाप का अंधकार बढ़ा।', - 'alert.prarabdhaBhoga.title': 'एक प्रारब्ध भोग लिया', - 'alert.prarabdhaBhoga.subtitle': '{n} शेष।', - 'alert.prarabdhaMukta.title': 'प्रारब्ध से मुक्ति', - 'alert.prarabdhaMukta.subtitle': 'पूर्ण भोग संपन्न!', + 'alert.praarabdhaBhoga.title': 'एक प्रारब्ध भोग लिया', + 'alert.praarabdhaBhoga.subtitle': '{n} शेष।', + 'alert.praarabdhaMukta.title': 'प्रारब्ध से मुक्ति', + 'alert.praarabdhaMukta.subtitle': 'पूर्ण भोग संपन्न!', 'alert.gamepad.title': 'गेमपैड जुड़ा', 'alert.gamepad.subtitle': 'नियंत्रण सक्रिय।', 'alert.paused.title': 'खेल स्तम्भित', @@ -68,16 +68,16 @@ const STRINGS = { 'alert.errNaamaAbsent.subtitle': 'नाम जाप के लिए नाम की आवश्यकता है!', 'alert.errShankhaAbsent.title': 'शंख-शक्ति समाप्त', 'alert.errShankhaAbsent.subtitle': 'पहले शंख संग्रह करें।', - 'alert.errJyotiAbsent.title': 'ज्योति-शक्ति समाप्त', - 'alert.errJyotiAbsent.subtitle': 'पहले ज्योति संग्रह करें।', + 'alert.errVisionbAbsent.title': 'ज्योति-शक्ति समाप्त', + 'alert.errVisionbAbsent.subtitle': 'पहले ज्योति संग्रह करें।', 'alert.errSamarpanaPhase.title': 'समर्पण अस्वीकृत', 'alert.errSamarpanaPhase.subtitle': "नाम समर्पण केवल 'अंतिम चरण' में संभव है।", 'alert.errSamarpanaNoNaam.title': 'समर्पण अस्वीकृत', 'alert.errSamarpanaNoNaam.subtitle': 'समर्पण हेतु नाम शेष नहीं है।', 'alert.errSamarpanaTunnel.title': 'समर्पण अस्वीकृत', 'alert.errSamarpanaTunnel.subtitle': 'नाम समर्पण करने के लिए आपको भक्ति-मार्ग के अंदर होना चाहिए।', - 'alert.errPrarabdhaMax.title': 'प्रारब्ध सीमा', - 'alert.errPrarabdhaMax.subtitle': 'अधिकतम {n} — नया बोझ असंभव।', + 'alert.errPraarabdhaMax.title': 'प्रारब्ध सीमा', + 'alert.errPraarabdhaMax.subtitle': 'अधिकतम {n} — नया बोझ असंभव।', // ── पुनर्जन्म ── 'alert.punarjanmaApavitra.title': 'अपवित्र पुनर्जन्म', 'alert.punarjanmaApavitra.subtitle': 'कर्म असंतुलित रह गया, चक्र जारी है...', @@ -140,10 +140,10 @@ const STRINGS = { 'tutorial.tunnel.task': 'स्क्रीन के मध्य में चमकता भक्ति-मार्ग दिखेगा।\nउसमें प्रवेश करो।', 'tutorial.tunnel.hint': 'भक्ति-मार्ग में नाम-समर्पण (↑) संभव होता है।', - 'tutorial.prarabdha.credit': '— स्कन्द पुराण', - 'tutorial.prarabdha.meaning': '', - 'tutorial.prarabdha.task': 'प्रारब्ध भोगना ही पड़ता है — टाला नहीं जा सकता।\nमृत्यु पर प्रारब्ध +१ जुड़ता है। धैर्य रखो।\n\n"ENTER" दबाओ — यात्रा शुरू हो!', - 'tutorial.prarabdha.hint': 'पुण्य, नाम, और समर्पण से मोक्ष मिलता है।', + 'tutorial.praarabdha.credit': '— स्कन्द पुराण', + 'tutorial.praarabdha.meaning': '', + 'tutorial.praarabdha.task': 'प्रारब्ध भोगना ही पड़ता है — टाला नहीं जा सकता।\nमृत्यु पर प्रारब्ध +१ जुड़ता है। धैर्य रखो।\n\n"ENTER" दबाओ — यात्रा शुरू हो!', + 'tutorial.praarabdha.hint': 'पुण्य, नाम, और समर्पण से मोक्ष मिलता है।', // ── अंत-स्क्रीन (End screens) ── // ⚠️ केवल पाठ — CSS/styles code में रहते हैं, यहाँ कभी नहीं। @@ -174,16 +174,17 @@ const STRINGS = { // ── HUD canvas text ── 'hud.finalPhase': 'अंतिम चरण', 'hud.punyaTimerLabel': 'पुण्य +', - 'hud.prarabdhaTimerLabel': 'प्रारब्ध {n} शेष', + 'hud.praarabdhaTimerLabel': 'प्रारब्ध {n} शेष', // ── notify overlay ── - 'notify.prarabdhaMukta': '📜🔥 मुक्त!', + 'notify.praarabdhaMukta': '📜🔥 मुक्त!', // ── end screens ── 'end.punarjanmaLabel': 'पुनर्जन्म:', 'end.moksha.samayaLabel': 'मोक्ष 🌿', 'end.restartHint': "'R' दबाएं जीवन रथ को पुनः आरंभ करने के लिए", + 'end.punarjanmaBtn': '♻️ पुनर्जन्म', // ── शास्त्र-ग्रंथ (navigation) ── - 'shastra.next': 'अगला [ {page} / {total} ]', - 'shastra.prev': 'पिछला [ {page} / {total} ]', + 'shaashtra.next': 'अगला [ {page} / {total} ]', + 'shaashtra.prev': 'पिछला [ {page} / {total} ]', }, en: { 'start.title': 'MOKSHA', @@ -195,11 +196,11 @@ const STRINGS = { 'start.pageDescription': 'Moksha - Break free from the cycle of life and death.', 'start.tutorialButton': '🕉️ Get Guru-diksha', 'viraama.title': '॥ PAUSED ॥', - 'viraama.resume': 'Resume', - 'viraama.restart': 'Restart', - 'viraama.quit': 'Quit', - 'shastra.title': '॥ Shaastra ॥', - 'shastra.subtitle':'Knowledge of the Chariot', + 'viraama.resume': 'Keep Dreaming', + 'viraama.restart': 'New Dream', + 'viraama.quit': 'Wake Up', + 'shaashtra.title': '॥ Shaastra ॥', + 'shaashtra.subtitle':'Knowledge of the Chariot', 'tutorial.dismiss':'ENTER / TAP to continue', 'loading.text': 'Preparing the chariot...', 'alert.samaya200.title': 'Samaya (time) is running out', @@ -215,17 +216,17 @@ const STRINGS = { 'alert.samarpita.title': '{n} Samarpita!', 'alert.samarpita10.subtitle': 'First milestone — the path of surrender opens.', 'alert.samarpita25.subtitle': 'Well done! Keep acting without attachment.', - 'alert.samarpita50.subtitle': 'Remarkable! Moving toward complete Vairagya.', + 'alert.samarpita50.subtitle': 'Remarkable! Moving toward complete Vairaagya.', 'alert.chakravaata.title': 'Chakravata (storm) near', 'alert.chakravaataShankha.subtitle': 'Press Y — destroy it with the Shankha!', 'alert.chakravaataNone.subtitle': 'Gather a Shankha — you are unprotected.', 'alert.drishti.title': 'Vision obscured', - 'alert.drishtiJyoti.subtitle': 'Press B — dispel the dark with Jyoti.', - 'alert.drishtiNone.subtitle': 'Gather Jyoti — the dark of Papa is growing.', - 'alert.prarabdhaBhoga.title': 'One Prarabdha endured', - 'alert.prarabdhaBhoga.subtitle': '{n} remaining.', - 'alert.prarabdhaMukta.title': 'Freed from Prarabdha', - 'alert.prarabdhaMukta.subtitle': 'The enduring is complete!', + 'alert.drishtiVisionb.subtitle': 'Press B — dispel the dark with Visionb.', + 'alert.drishtiNone.subtitle': 'Gather Visionb — the dark of Papa is growing.', + 'alert.praarabdhaBhoga.title': 'One Praarabdha endured', + 'alert.praarabdhaBhoga.subtitle': '{n} remaining.', + 'alert.praarabdhaMukta.title': 'Freed from Praarabdha', + 'alert.praarabdhaMukta.subtitle': 'The enduring is complete!', 'alert.gamepad.title': 'Gamepad connected', 'alert.gamepad.subtitle': 'Controls active.', 'alert.paused.title': 'Game paused', @@ -238,38 +239,38 @@ const STRINGS = { 'alert.bandhanaPaapaMukta.subtitle': 'Inauspicious karma burnt — the soul is pure.', 'alert.bandhanaPaapaShesha.title': 'Papa-bondage', 'alert.bandhanaPaapaShesha.subtitle': '{n} remaining — 5 more Naama needed.', - 'alert.kripaSamarpita.title': 'Kripa (grace)', + 'alert.kripaSamarpita.title': 'Blessing (grace)', 'alert.kripaSamarpita.subtitle': 'All worldly Punya and Papa have been surrendered.', - 'alert.kripaSimple.title': 'Kripa received', + 'alert.kripaSimple.title': 'Blessing received', 'alert.kripaSimple.subtitle': '', - 'alert.shankhaPrapta.title': 'Shankha (conch) received', - 'alert.jyotiPrapta.title': 'Jyoti (lamp) received', + 'alert.shankhaPrapta.title': 'Conch received', + 'alert.jyotiPrapta.title': 'Vision received', 'alert.shankhaPrapta.subtitle': 'Keep it safe — it quells the Chakravata.', 'alert.jyotiPrapta.subtitle': 'Press B to spread light in the darkness.', 'alert.errNaamaAbsent.title': 'Cannot chant', 'alert.errNaamaAbsent.subtitle': 'Naama-Japa requires collected Naama!', 'alert.errShankhaAbsent.title': 'No Shankha left', 'alert.errShankhaAbsent.subtitle': 'Gather a Shankha first.', - 'alert.errJyotiAbsent.title': 'No Jyoti left', - 'alert.errJyotiAbsent.subtitle': 'Gather a Jyoti first.', + 'alert.errVisionbAbsent.title': 'No Visionb left', + 'alert.errVisionbAbsent.subtitle': 'Gather a Visionb first.', 'alert.errSamarpanaPhase.title': 'Samarpana refused', 'alert.errSamarpanaPhase.subtitle': 'Naama-Samarpana is possible only in the final phase.', 'alert.errSamarpanaNoNaam.title': 'Samarpana refused', 'alert.errSamarpanaNoNaam.subtitle': 'No Naama left to surrender.', 'alert.errSamarpanaTunnel.title': 'Samarpana refused', 'alert.errSamarpanaTunnel.subtitle': 'You must be inside the Bhakti path to surrender the Naama.', - 'alert.errPrarabdhaMax.title': 'Prarabdha limit', - 'alert.errPrarabdhaMax.subtitle': 'Maximum {n} — no further burden possible.', + 'alert.errPraarabdhaMax.title': 'Praarabdha limit', + 'alert.errPraarabdhaMax.subtitle': 'Maximum {n} — no further burden possible.', // ── Rebirth ── - 'alert.punarjanmaApavitra.title': 'Impure Punarjanma', + 'alert.punarjanmaApavitra.title': 'Impure Rebirth', 'alert.punarjanmaApavitra.subtitle': 'Karma remained unbalanced; the cycle continues...', - 'alert.punarjanmaPavitra.title': 'Pure Punarjanma', + 'alert.punarjanmaPavitra.title': 'Pure Rebirth', 'alert.punarjanmaPavitra.subtitle': 'Karma was pure, but the journey stayed unfinished.', - 'alert.punarjanmaNaya.title': 'Pure Punarjanma', + 'alert.punarjanmaNaya.title': 'Pure Rebirth', 'alert.punarjanmaNaya.subtitle': 'A new journey begins.', - 'alert.kripaAtirikta.title': 'Extra Kripa', - 'alert.kripaAtirikta.subtitle': 'Entering the new life carrying Kripa!', + 'alert.kripaAtirikta.title': 'Extra Blessing', + 'alert.kripaAtirikta.subtitle': 'Entering the new life carrying Blessing!', // ── Actions ── 'alert.naamaSumirana.title': 'Naama-Sumirana', @@ -282,15 +283,15 @@ const STRINGS = { 'alert.punyaPrapta.subtitle': "The charioteer's mind accepted good deeds.", 'alert.ashuvha.title': 'Papa strikes', 'alert.ashuvha.subtitle': 'The chariot was struck by inauspicious karma!', - 'alert.naamaSamarpita.title': 'Naama surrendered', + 'alert.naamaSamarpita.title': 'Poorna surrendered', 'alert.naamaSamarpita.subtitle': '+{n} received.', - 'alert.vairaagya.title': 'Vairagya (detachment)', + 'alert.vairaagya.title': 'Vairaagya (detachment)', 'alert.vairaagya.subtitle': 'The charioteer refused the lure of Punya.', 'alert.shankhaNaada.title': 'Shankha-nada', 'alert.shankhaNaada.subtitle': 'White light is spreading...', 'alert.shankhaChakra.title': 'Shankha-nada', 'alert.shankhaChakra.subtitle': 'The Chakravata was surrendered.', - 'alert.jyotiJali.title': 'Jyoti lit', + 'alert.jyotiJali.title': 'Visionb lit', 'alert.jyotiJali.subtitle': 'Light is spreading in the dark of Papa...', 'alert.brahmandaKshitija.title': 'Cosmic horizon', 'alert.brahmandaKshitija.subtitle': 'Time stands still — the moment of decision.', @@ -314,7 +315,7 @@ const STRINGS = { 'tutorial.maya.hint': 'Recognising Maya — that is the first step.', 'tutorial.jaapa.credit': '— Raamacharitmaanasa', - 'tutorial.jaapa.meaning': 'By chanting the Naama, auspiciousness arises in all ten directions.', + 'tutorial.jaapa.meaning': 'Naama brings auspiciousness in all ten directions.', 'tutorial.jaapa.task': 'Chant the Naama.\nKeyboard: SPACE | Gamepad: RT\n(works only when Naama has been collected)', 'tutorial.jaapa.hint': 'The Naama alone protects — chant it again and again.', @@ -323,13 +324,13 @@ const STRINGS = { 'tutorial.tunnel.task': 'A glowing Bhakti path appears in the middle of the screen.\nEnter it.', 'tutorial.tunnel.hint': 'Naama-Samarpana (↑) is possible within the Bhakti path.', - 'tutorial.prarabdha.credit': '— Skanda Purana', - 'tutorial.prarabdha.meaning': 'Papa wanes through enduring; impurity wanes through tapas.', - 'tutorial.prarabdha.task': 'Prarabdha must be endured — it cannot be avoided.\nOn death, Prarabdha increases by 1. Be patient.\n\nPress "ENTER" — let the journey begin!', - 'tutorial.prarabdha.hint': 'Moksha comes through Punya, Naama, and Samarpana.', + 'tutorial.praarabdha.credit': '— Skanda Purana', + 'tutorial.praarabdha.meaning': 'Papa wanes through enduring; impurity wanes through tapas.', + 'tutorial.praarabdha.task': 'Praarabdha must be endured — it cannot be avoided.\nOn death, Praarabdha increases by 1. Be patient.\n\nPress "ENTER" — let the journey begin!', + 'tutorial.praarabdha.hint': 'Moksha comes through Punya, Naama, and Samarpana.', // ── End screens ── - 'end.pralaya.title': '🛑 PRALAYA 🛑', + 'end.pralaya.title': '🛑 WOKE UP 🛑', 'end.pralaya.lead': 'Journey abandoned:', 'end.pralaya.line1': 'The charioteer let go of the chariot midway.', 'end.pralaya.stats': 'State of mind — Punya: {punya} | Papa: {paap}', @@ -342,7 +343,7 @@ const STRINGS = { 'end.moksha.heading': 'Beyond the gunas and beyond karma', 'end.moksha.line3': 'A rare realisation! The charioteer held the horses of the senses still, and freed the mind wholly from attachment.', - 'end.rebirth.title': 'Punarjanma in the world', + 'end.rebirth.title': 'Rebirth in the world', 'end.rebirth.lead': 'The reins of Moha (delusion):', 'end.rebirth.paap': 'Your ({n}) Papa blinded the charioteer.', 'end.rebirth.punya': 'The mind grew attached to your ({n}) Punya.', @@ -351,15 +352,16 @@ const STRINGS = { // ── HUD canvas text ── 'hud.finalPhase': 'Final Phase', 'hud.punyaTimerLabel': 'Punya +', - 'hud.prarabdhaTimerLabel': 'Prarabdha {n} remaining', + 'hud.praarabdhaTimerLabel': 'Praarabdha {n} remaining', // ── notify overlay ── - 'notify.prarabdhaMukta': '📜🔥 Freed!', + 'notify.praarabdhaMukta': '📜🔥 Freed!', // ── end screens ── 'end.punarjanmaLabel': 'Rebirths:', 'end.moksha.samayaLabel': 'Moksha 🌿', 'end.restartHint': "Press 'R' to restart the life chariot", - 'shastra.next': 'Next [ {page} / {total} ]', - 'shastra.prev': 'Back [ {page} / {total} ]', + 'end.punarjanmaBtn': '♻️ Punarjanma', + 'shaashtra.next': 'Next [ {page} / {total} ]', + 'shaashtra.prev': 'Back [ {page} / {total} ]', }, }; diff --git a/src/karma.js b/src/karma.js index 1abe11d..aadb577 100644 --- a/src/karma.js +++ b/src/karma.js @@ -42,7 +42,7 @@ export const KarmaMixin = { _syncOrbitCounts() { this.outerOrbits[0].count = this.shuvhaKarma; this.outerOrbits[1].count = this.ashuvhaKarma; - this.outerOrbits[2].count = this.prarabdha; + this.outerOrbits[2].count = this.praarabdha; this.outerOrbits[3].count = this.activeNaam; this.outerOrbits[4].count = this.kripa; this.outerOrbits[5].count = this.shankha; @@ -63,9 +63,9 @@ export const KarmaMixin = { this.shuvhaKarma === 0 && this.ashuvhaKarma === 0 && !this._pendingGoodKarma && - this.prarabdha === 0 && + this.praarabdha === 0 && this.chetanaaJaagrita && - this.purnaSamarpana + this.poornaSamarpana ) { if (this._UI?.samayaVal) this._UI.samayaVal.innerText = t('end.moksha.samayaLabel'); if (this._UI?.swaansaVal) this._UI.swaansaVal.innerText = `0`; if (!this.gameOver) { @@ -82,7 +82,7 @@ export const KarmaMixin = { this.activeNaam >= 20 || this.samarpita >= 30 || this.chetanaaJaagrita ); // ── Bug 5 fix: pendingGoodKarma clear करने से पहले capture करें ── - // पहले false किया → hasSanchitaKarma में already false → prarabdha +1 miss + // पहले false किया → hasSanchitaKarma में already false → praarabdha +1 miss const _hadPendingKarma = this._pendingGoodKarma; // ── pendingGoodKarma साफ करें — प्रारब्ध में count नहीं जोड़ेंगे ── @@ -98,24 +98,24 @@ export const KarmaMixin = { // एक जन्म का भार = एक प्रारब्ध। // _hadPendingKarma: captured value — clear होने से पहले का सच const hasSanchitaKarma = (this.shuvhaKarma > 0 || this.ashuvhaKarma > 0 || _hadPendingKarma); - const prevPrarabdha = this.prarabdha; + const prevPraarabdha = this.praarabdha; if (hasSanchitaKarma) { - this.prarabdha = Math.min(MAX_PRARABDHA, this.prarabdha + 1); + this.praarabdha = Math.min(MAX_PRARABDHA, this.praarabdha + 1); } - const actualAdded = this.prarabdha - prevPrarabdha; + const actualAdded = this.praarabdha - prevPraarabdha; if (actualAdded > 0) { - this.prarabdhaTimer += PRARABDHA_BHOG_FRAMES; // सदा 1× — +1 प्रारब्ध = 1 भोग-चक्र + this.praarabdhaTimer += PRARABDHA_BHOG_FRAMES; // सदा 1× — +1 प्रारब्ध = 1 भोग-चक्र this._addFloatingText(`+1 📜`, "#a78bfa"); } // cap hit होने पर player को सूचित करें if (hasSanchitaKarma && actualAdded === 0) { - this._alertKey('errPrarabdhaMax', '⚠️', 'warning', { n: MAX_PRARABDHA }); + this._alertKey('errPraarabdhaMax', '⚠️', 'warning', { n: MAX_PRARABDHA }); } - // पूर्व-जन्म का gati-भार prarabdha में store करें — multiply (हर जन्म का बोझ जुड़े) - this.prarabdhaGatiModifier *= this._currentGatiModifier; + // पूर्व-जन्म का gati-भार praarabdha में store करें — multiply (हर जन्म का बोझ जुड़े) + this.praarabdhaGatiModifier *= this._currentGatiModifier; // 0 तक न जाने दें — minimum gati 1% बनाए रखें - this.prarabdhaGatiModifier = Math.max(0.01, this.prarabdhaGatiModifier); + this.praarabdhaGatiModifier = Math.max(0.01, this.praarabdhaGatiModifier); this.ashuvhaKarma = 0; this.shuvhaKarma = 0; this.punaraJanmaCount++; this._triggerBlast("#f87171"); this.samaya = SAMAYA_PRAARAMBHIKA; @@ -133,7 +133,7 @@ export const KarmaMixin = { // चेतना जागृत है तो पुनर्जन्म पर भी कर्म-रक्षा बनी रहे this.isKarmaImmune = this.chetanaaJaagrita; - this.purnaSamarpana = false; + this.poornaSamarpana = false; if (isApavitra) { this._alertKey('punarjanmaApavitra', '♻️', 'warning'); @@ -468,7 +468,7 @@ export const KarmaMixin = { this.activeNaam = 0; this.shankha = 0; this.jyoti = 0; - this.purnaSamarpana = true; + this.poornaSamarpana = true; this.isKarmaImmune = true; this._addFloatingText(`+${gained} ॐ🙏`, "#ffff00", { alpha:1.5, vy:-2, isBigName:true, yOffset:-10 }); this._alertKey('naamaSamarpita', '🌿', 'achievement', { n: gained }); diff --git a/src/main.js b/src/main.js index cccef36..4cab04b 100644 --- a/src/main.js +++ b/src/main.js @@ -14,7 +14,7 @@ * • Event listeners (keyboard, gamepad, buttons, wheel) * • scaleGame() / debounce() * • Gamepad module (pollGamepad, vibrateGamepad, etc.) - * • Shastra navigation (toggleShastra, updateShastraPage) + * • Shaashtra navigation (toggleShaashtra, updateShaashtraPage) * • draw() — engine.getState() + Renderer calls * • gameLoop() — रा॒फ़ loop * • Start-screen poller @@ -26,7 +26,7 @@ import { Renderer } from './render.js'; import { KarmaEngine, SAMAYA_PRAARAMBHIKA } from './engine.js'; import Audio from './audio.js'; import { TutorialManager } from './tutorial.js'; -import { renderShastraPage } from './shastra.js'; +import { renderShaashtraPage } from './shaashtra.js'; import { TouchControls } from './touch.js'; const AM = Audio; // ====================== CANVAS SETUP ====================== @@ -50,14 +50,14 @@ const UI = { naama: document.getElementById('naama'), punya: document.getElementById('punya'), paap: document.getElementById('paap'), - prarabdha: document.getElementById('prarabdha'), + praarabdha: document.getElementById('praarabdha'), samarpita: document.getElementById('samarpita'), punaraJanma: document.getElementById('punaraJanma'), kripa: document.getElementById('kripa'), shankha: document.getElementById('shankha'), jyoti: document.getElementById('jyoti'), drishti: document.getElementById('drishti'), - purnaSamarpana: document.getElementById('purnaSamarpana'), + poornaSamarpana: document.getElementById('poornaSamarpana'), chetana: document.getElementById('chetana'), samayaVal: document.getElementById('ui-samaya-val'), swaansaVal: document.getElementById('ui-swaansa-val'), @@ -67,7 +67,8 @@ const UI = { overlayTitle: document.getElementById('overlay-title'), overlaySubtitle: document.getElementById('overlay-subtitle'), viraamaOverlay: document.getElementById('viraama-overlay'), - shastraOverlay: document.getElementById('shastra-overlay'), + shaashtraOverlay: document.getElementById('shaashtra-overlay'), + punarjanmaBtn: document.getElementById('punarjanma-btn'), }; // ====================== ENGINE INIT ====================== @@ -107,10 +108,10 @@ let isFontsReady = false; let isScaleGameDone = false; // ====================== SHASTRA STATE ====================== -let currentShastraPage = 1; +let currentShaashtraPage = 1; // 🛠️ key-repeat बिना continuous scroll (dpad-stick जैसी consistency) -let shastraKeyState = { up: false, down: false }; -const shastraBody = document.getElementById('shastra-body'); // one time cashe +let shaashtraKeyState = { up: false, down: false }; +const shaashtraBody = document.getElementById('shaashtra-body'); // one time cashe // ====================== GAMEPAD MODULE ====================== const GAMEPAD_DEADZONE = 0.18; @@ -154,14 +155,14 @@ function handleDiscreteButton(gp, buttonIndex, keyName) { } /** edge-triggered helper for any boolean condition */ -function handleShastraDirection(stateKey, isActiveNow, onRise) { +function handleShaashtraDirection(stateKey, isActiveNow, onRise) { const wasActive = !!gpButtonStates[stateKey]; if (isActiveNow && !wasActive) onRise(); gpButtonStates[stateKey] = isActiveNow; } /** शास्त्र-नेविगेशन (shared between pollGamepad + pollGamepadOnStartScreen) */ -function handleShastraGamepadNav(gp) { +function handleShaashtraGamepadNav(gp) { const stickX = gp.axes[0] || 0; const stickY = gp.axes[1] || 0; const dpadLeft = !!gp.buttons[GAMEPAD_BUTTON.DPAD_LEFT]?.pressed; @@ -172,14 +173,14 @@ function handleShastraGamepadNav(gp) { const left = (stickX < -GAMEPAD_DEADZONE) || dpadLeft; const right = (stickX > GAMEPAD_DEADZONE) || dpadRight; - handleShastraDirection('shastra_left', left, () => dispatchKey('keydown', 'ArrowLeft')); - handleShastraDirection('shastra_right', right, () => dispatchKey('keydown', 'ArrowRight')); - handleShastraDirection('shastra_dpad_up', dpadUp, () => dispatchKey('keydown', 'PageUp')); - handleShastraDirection('shastra_dpad_down', dpadDown,() => dispatchKey('keydown', 'PageDown')); + handleShaashtraDirection('shaashtra_left', left, () => dispatchKey('keydown', 'ArrowLeft')); + handleShaashtraDirection('shaashtra_right', right, () => dispatchKey('keydown', 'ArrowRight')); + handleShaashtraDirection('shaashtra_dpad_up', dpadUp, () => dispatchKey('keydown', 'PageUp')); + handleShaashtraDirection('shaashtra_dpad_down', dpadDown,() => dispatchKey('keydown', 'PageDown')); // Analog stick → smooth scroll (collision-free) if (stickY < -GAMEPAD_DEADZONE || stickY > GAMEPAD_DEADZONE) { - const body = document.getElementById('shastra-body'); + const body = document.getElementById('shaashtra-body'); if (body) body.scrollTop += stickY * 6 * 2; } } @@ -207,8 +208,8 @@ function pollGamepad() { } gpButtonStates['_tut_start'] = _tStartPressed; - if (engine.isShastraVisible) { - handleShastraGamepadNav(gp); + if (engine.isShaashtraVisible) { + handleShaashtraGamepadNav(gp); keys['arrowleft'] = false; keys['arrowright'] = false; } else { // Movement @@ -230,7 +231,7 @@ function pollGamepad() { // ====================== SHASTRA UI ====================== -function updateShastraPage() { +function updateShaashtraPage() { const lang = getLang(); const TOTAL = 3; @@ -238,62 +239,62 @@ function updateShastraPage() { // dataset.lang से जाँचते हैं कि यह page पहले से इसी भाषा में तो नहीं; // वरना हर nav-click पर व्यर्थ innerHTML लिखना पड़ता। for (let p = 1; p <= TOTAL; p++) { - const el = document.getElementById(`shastra-page-${p}`); + const el = document.getElementById(`shaashtra-page-${p}`); if (el && el.dataset.lang !== lang) { - el.innerHTML = renderShastraPage(p - 1, lang); // 0-based index + el.innerHTML = renderShaashtraPage(p - 1, lang); // 0-based index el.dataset.lang = lang; } } for (let p = 1; p <= 3; p++) { - document.getElementById(`shastra-page-${p}`)?.classList.remove('active'); + document.getElementById(`shaashtra-page-${p}`)?.classList.remove('active'); } - document.getElementById(`shastra-page-${currentShastraPage}`)?.classList.add('active'); - const navBtn = document.getElementById('shastra-nav-btn'); + document.getElementById(`shaashtra-page-${currentShaashtraPage}`)?.classList.add('active'); + const navBtn = document.getElementById('shaashtra-nav-btn'); if (navBtn) { - const key = currentShastraPage < TOTAL ? 'shastra.next' : 'shastra.prev'; - navBtn.textContent = t(key, { page: currentShastraPage, total: TOTAL }); + const key = currentShaashtraPage < TOTAL ? 'shaashtra.next' : 'shaashtra.prev'; + navBtn.textContent = t(key, { page: currentShaashtraPage, total: TOTAL }); } } /** * शास्त्र toggle — engine state + DOM overlay एक साथ update। - * (DRY: ESC key, shastra-help-btn, shastra-close-btn तीनों यही बुलाते हैं) + * (DRY: ESC key, shaashtra-help-btn, shaashtra-close-btn तीनों यही बुलाते हैं) */ -function toggleShastra() { - engine.toggleShastra(); // engine internal state update - if (engine.isShastraVisible) { - touch.block('shastra'); +function toggleShaashtra() { + engine.toggleShaashtra(); // engine internal state update + if (engine.isShaashtraVisible) { + touch.block('shaashtra'); // overlay DOM - currentShastraPage = 1; updateShastraPage(); + currentShaashtraPage = 1; updateShaashtraPage(); // keys reassign नहीं — TouchControls reference safe रहे Object.keys(keys).forEach(k => { keys[k] = false; }); touch.clearAll(); } else { - touch.unblock('shastra'); + touch.unblock('shaashtra'); Object.keys(keys).forEach(k => { keys[k] = false; }); touch.clearAll(); - // engine.toggleShastra() already restores pause state correctly. + // engine.toggleShaashtra() already restores pause state correctly. // Only reset lastTime when the game is actually unpaused. if (!engine.isPaused) { - lastTime = performance.now(); // Shastra में बिताया time → dt spike रोकें + lastTime = performance.now(); // Shaashtra में बिताया time → dt spike रोकें } } } // ====================== CONTINUOUS SHASTRA SCROLL ====================== // ArrowUp/Down को OS key-repeat पर निर्भर न रखकर — held-flag से smooth scroll -let _shastraScrollRafId = null; -function continuousShastraScrollLoop() { - if (engine.isShastraVisible) { - const body = document.getElementById('shastra-body'); +let _shaashtraScrollRafId = null; +function continuousShaashtraScrollLoop() { + if (engine.isShaashtraVisible) { + const body = document.getElementById('shaashtra-body'); if(body) { - if (shastraKeyState.up) body.scrollTop -= 6; - if (shastraKeyState.down) body.scrollTop += 6; + if (shaashtraKeyState.up) body.scrollTop -= 6; + if (shaashtraKeyState.down) body.scrollTop += 6; } } - _shastraScrollRafId = requestAnimationFrame(continuousShastraScrollLoop); + _shaashtraScrollRafId = requestAnimationFrame(continuousShaashtraScrollLoop); } -_shastraScrollRafId = requestAnimationFrame(continuousShastraScrollLoop); +_shaashtraScrollRafId = requestAnimationFrame(continuousShaashtraScrollLoop); // ====================== UTILITY ====================== function debounce(func, delay) { @@ -333,11 +334,11 @@ window.addEventListener('orientationchange', () => setTimeout(scaleGame, 300)); // ====================== EVENT LISTENERS ====================== -// ── Wheel (shastra scroll) ── +// ── Wheel (shaashtra scroll) ── window.addEventListener('wheel', (e) => { - if (!engine.isShastraVisible) return; + if (!engine.isShaashtraVisible) return; e.preventDefault(); - const body = document.getElementById('shastra-body'); + const body = document.getElementById('shaashtra-body'); if (body) body.scrollTop += e.deltaY; // direct — collision-free }, { passive: false }); @@ -345,7 +346,7 @@ window.addEventListener('wheel', (e) => { window.addEventListener('keydown', (e) => { const key = e.key.toLowerCase(); - if (!isGameStarted && key !== 'escape' && !engine.isShastraVisible) return; + if (!isGameStarted && key !== 'escape' && !engine.isShaashtraVisible) return; AM?.ensureAudio(); if (['arrowup','arrowdown','arrowleft','arrowright',' ','q','f','r','escape','enter','pageup','pagedown'].includes(key)) { @@ -356,17 +357,17 @@ window.addEventListener('keydown', (e) => { if (key === 'enter') { tutorial.dismiss(); return; } if (key === 'escape') { if (!tutorial.isDone()) { tutorial.skip(); return; } - toggleShastra(); return; + toggleShaashtra(); return; } - if (engine.isShastraVisible) { - const body = document.getElementById('shastra-body'); - if (key === 'arrowleft' && currentShastraPage > 1) { currentShastraPage--; updateShastraPage(); if (body) body.scrollTop = 0; } - if (key === 'arrowright' && currentShastraPage < 3) { currentShastraPage++; updateShastraPage(); if (body) body.scrollTop = 0; } - if (key === 'arrowup') shastraKeyState.up = true; - if (key === 'arrowdown') shastraKeyState.down = true; + if (engine.isShaashtraVisible) { + const body = document.getElementById('shaashtra-body'); + if (key === 'arrowleft' && currentShaashtraPage > 1) { currentShaashtraPage--; updateShaashtraPage(); if (body) body.scrollTop = 0; } + if (key === 'arrowright' && currentShaashtraPage < 3) { currentShaashtraPage++; updateShaashtraPage(); if (body) body.scrollTop = 0; } + if (key === 'arrowup') shaashtraKeyState.up = true; + if (key === 'arrowdown') shaashtraKeyState.down = true; if (key === 'pageup') { if (body) body.scrollTop -= body.clientHeight * 0.9; } if (key === 'pagedown') { if (body) body.scrollTop += body.clientHeight * 0.9; } return; @@ -396,8 +397,8 @@ window.addEventListener('keydown', (e) => { window.addEventListener('keyup', (e) => { const key = e.key.toLowerCase(); keys[key] = false; - if (key === 'arrowup') shastraKeyState.up = false; - if (key === 'arrowdown') shastraKeyState.down = false; + if (key === 'arrowup') shaashtraKeyState.up = false; + if (key === 'arrowdown') shaashtraKeyState.down = false; }); window.addEventListener('blur', () => { @@ -437,7 +438,7 @@ window.addEventListener('gamepaddisconnected', (e) => { document.addEventListener('visibilitychange', () => { if (document.hidden && isGameStarted && !engine.gameOver && !engine.won && - !engine.isPaused && !engine.isShastraVisible) { + !engine.isPaused && !engine.isShaashtraVisible) { engine.isPaused = true; if (UI.viraamaOverlay) UI.viraamaOverlay.style.display = 'flex'; AM?.playSound('viraama'); @@ -456,6 +457,10 @@ document.getElementById('restart-btn')?.addEventListener('click', () => { UI.viraamaOverlay.style.display = 'none'; engine.reset(); lastTime = performance.now(); }); +// ── पुनर्जन्म बटन (end screen) — प्रलय/पुनर्जन्म के बाद नया चक्र ── +document.getElementById('punarjanma-btn')?.addEventListener('click', () => { + engine.reset(); lastTime = performance.now(); +}); document.getElementById('quit-btn')?.addEventListener('click', () => { UI.viraamaOverlay.style.display = 'none'; engine.actionPralaya(); @@ -463,16 +468,16 @@ document.getElementById('quit-btn')?.addEventListener('click', () => { document.getElementById('music-toggle-btn')?.addEventListener('click', () => { AM?.ensureAudio(); AM?.toggleBgMusic(); }); -document.getElementById('shastra-help-btn')?.addEventListener('click', () => { - AM?.ensureAudio(); toggleShastra(); +document.getElementById('shaashtra-help-btn')?.addEventListener('click', () => { + AM?.ensureAudio(); toggleShaashtra(); }); -document.getElementById('shastra-close-btn')?.addEventListener('click', () => { - toggleShastra(); +document.getElementById('shaashtra-close-btn')?.addEventListener('click', () => { + toggleShaashtra(); }); -document.getElementById('shastra-nav-btn')?.addEventListener('click', () => { - currentShastraPage = currentShastraPage < 3 ? currentShastraPage + 1 : 1; - updateShastraPage(); - const body = document.getElementById('shastra-body'); +document.getElementById('shaashtra-nav-btn')?.addEventListener('click', () => { + currentShaashtraPage = currentShaashtraPage < 3 ? currentShaashtraPage + 1 : 1; + updateShaashtraPage(); + const body = document.getElementById('shaashtra-body'); if (body) body.scrollTop = 0; }); document.getElementById('music-volume-slider')?.addEventListener('input', (e) => { @@ -525,7 +530,7 @@ lastTime = performance.now(); function gameLoop(ts) { pollGamepad(); - if (!engine.isPaused && !engine.gameOver && !engine.won && !engine.isShastraVisible) { + if (!engine.isPaused && !engine.gameOver && !engine.won && !engine.isShaashtraVisible) { const rawDt = Math.min((ts - lastTime) / (1000 / 60), 2); // tutorial card visible होने पर slow-motion (dt × 0.3) const dt = tutorial.isSlowMode() ? rawDt * 0.3 : rawDt; @@ -592,9 +597,11 @@ function applyStartScreenLanguage() { metaDescription?.setAttribute('content', t('start.pageDescription')); hindiLabel?.classList.toggle('active', !isEnglish); englishLabel?.classList.toggle('active', isEnglish); - updateShastraPage(); // शास्त्र content भी language के अनुसार update करें - const restartHintEl = document.getElementById('restart-hint-text'); + updateShaashtraPage(); // शास्त्र content भी language के अनुसार update करें + const restartHintEl = document.getElementById('restart-hint-text'); if (restartHintEl) restartHintEl.textContent = t('end.restartHint'); + const punarjBtnEl = document.getElementById('punarjanma-btn'); + if (punarjBtnEl) punarjBtnEl.textContent = t('end.punarjanmaBtn'); // ── Pause (स्तम्भन) overlay — भाषा के अनुसार update ── const viraamaTitle = document.querySelector('.viraama-content h2'); @@ -606,11 +613,11 @@ function applyStartScreenLanguage() { if (restartBtnEl) restartBtnEl.textContent = t('viraama.restart'); if (quitBtn) quitBtn.textContent = t('viraama.quit'); - // ── Shastra overlay header — भाषा के अनुसार update ── - const shastraH2 = document.querySelector('#shastra-overlay .shastra-header h2'); - const shastraP = document.querySelector('#shastra-overlay .shastra-header p'); - if (shastraH2) shastraH2.textContent = t('shastra.title'); - if (shastraP) shastraP.textContent = t('shastra.subtitle'); + // ── Shaashtra overlay header — भाषा के अनुसार update ── + const shaashtraH2 = document.querySelector('#shaashtra-overlay .shaashtra-header h2'); + const shaashtraP = document.querySelector('#shaashtra-overlay .shaashtra-header p'); + if (shaashtraH2) shaashtraH2.textContent = t('shaashtra.title'); + if (shaashtraP) shaashtraP.textContent = t('shaashtra.subtitle'); // ── Loading overlay text — भाषा के अनुसार update ── const loadingText = document.getElementById('loading-overlay-text'); @@ -651,7 +658,7 @@ function pollGamepadOnStartScreen() { const startRise = startPressed && !startScreenGpState.start; startScreenGpState.start = startPressed; - if (startRise && !engine.isShastraVisible) { + if (startRise && !engine.isShaashtraVisible) { gpButtonStates[GAMEPAD_BUTTON.START] = true; startBtn?.click(); } @@ -662,7 +669,7 @@ function pollGamepadOnStartScreen() { startScreenGpState.back = backPressed; if (backRise) dispatchKey('keydown', 'Escape'); - if (engine.isShastraVisible) handleShastraGamepadNav(gp); + if (engine.isShaashtraVisible) handleShaashtraGamepadNav(gp); } requestAnimationFrame(pollGamepadOnStartScreen); @@ -707,7 +714,7 @@ AM?.setGameStateProvider?.(() => ({ gameOver: engine.gameOver, won: engine.won, isPaused: engine.isPaused, - isShastraVisible: engine.isShastraVisible, + isShaashtraVisible: engine.isShaashtraVisible, chetanaaJaagrita: engine.chetanaaJaagrita, })); // पुराना API compatibility @@ -716,7 +723,7 @@ AM?.setGameStateGetter?.(() => ({ gameOver: engine.gameOver, won: engine.won, isPaused: engine.isPaused, - isShastraVisible: engine.isShastraVisible, + isShaashtraVisible: engine.isShaashtraVisible, chetanaaJaagrita: engine.chetanaaJaagrita, })); AM?.setVibrateGamepad?.(vibrateGamepad); diff --git a/src/physics.js b/src/physics.js index 6125441..acdef3b 100644 --- a/src/physics.js +++ b/src/physics.js @@ -55,7 +55,7 @@ export const PhysicsMixin = { /** * सभी glow-rings निष्क्रिय/reset करें। - * punahaPrarambha (reset) में प्रयुक्त। + * punahaPraarambha (reset) में प्रयुक्त। */ _resetAllGlowRings() { for (let key in this.glowRings) { diff --git a/src/render.js b/src/render.js index 8d7f478..0942ae1 100644 --- a/src/render.js +++ b/src/render.js @@ -177,12 +177,12 @@ function drawKarmaChain(cx, baseY, color, strength = 1, isHeavy = false, frameNo ctx.save(); let swayPeriod = isHeavy ? 480 : 200; let pulse = Math.sin(frameNow / swayPeriod) * (isHeavy ? 7 : 5); - // prarabdha chain — orbits से visually अलग करने हेतु Y नीचे shift + // praarabdha chain — orbits से visually अलग करने हेतु Y नीचे shift let weightDropOffset = isHeavy ? (strength * 12) + 8 : 0; let y = baseY + pulse + weightDropOffset; let fontSize = isHeavy ? (32 + strength * 16) : (22 + strength * 14); - // prarabdha chain subtle opacity — orbit rings से distinguish हो + // praarabdha chain subtle opacity — orbit rings से distinguish हो ctx.globalAlpha = isHeavy ? 0.72 : 1.0; ctx.font = `${fontSize}px sans-serif`; ctx.textAlign = "center"; ctx.textBaseline = "middle"; ctx.shadowColor = color; ctx.shadowBlur = isHeavy ? (28 + strength * 22) : (25 + strength * 20); @@ -422,13 +422,13 @@ export const Renderer = { WIDTH, HEIGHT, TUNNEL_X, TUNNEL_WIDTH, SAMAYA_PRAARAMBHIKA, frameNow, shakeTimer, samaya, swaansaSamapta, stars, tunnelSparkles, particlePool, glowEffectPool, player, smoothSize, glowRings, - shuvhaKarma, ashuvhaKarma, prarabdha, activeNaam, kripa, shankha, jyoti, - samarpita, punaraJanmaCount, chetanaaJaagrita, purnaSamarpana, chainSlots, + shuvhaKarma, ashuvhaKarma, praarabdha, activeNaam, kripa, shankha, jyoti, + samarpita, punaraJanmaCount, chetanaaJaagrita, poornaSamarpana, chainSlots, finalHorsePositions, pulledHorseIndex, pulledHorseX, pulledHorseY, isPaused, gameOver, mayaPool, pendingGoodKarma, punyaTimer, pendingGoodKarmaCount, floatingTextPool, isNaamaJaapa, naamaGhera, outerOrbits, notifyTimer, notifyText, swaansaTimer, swaansa, - naamaGlowTimer, bodyGlowTimer, bodyGlowColor, prarabdhaTimer, + naamaGlowTimer, bodyGlowTimer, bodyGlowColor, praarabdhaTimer, alertQueue } = state; @@ -526,7 +526,7 @@ export const Renderer = { let activeChainCount = 0; if (shuvhaKarma > 0) { let s = chainSlots[activeChainCount++]; s.active = true; s.color = "#32ff32"; s.strength = Math.min(1, shuvhaKarma / 5); s.isHeavy = false; } if (ashuvhaKarma > 0) { let s = chainSlots[activeChainCount++]; s.active = true; s.color = "#ff3232"; s.strength = Math.min(1, ashuvhaKarma / 5); s.isHeavy = false; } - if (prarabdha > 0) { let s = chainSlots[activeChainCount++]; s.active = true; s.color = "#8b0000"; s.strength = Math.min(1, prarabdha / 10); s.isHeavy = true; } + if (praarabdha > 0) { let s = chainSlots[activeChainCount++]; s.active = true; s.color = "#8b0000"; s.strength = Math.min(1, praarabdha / 10); s.isHeavy = true; } for (let i = activeChainCount; i < chainSlots.length; i++) chainSlots[i].active = false; drawCenteredRow(cx, cy + 50, activeChainCount, CHAIN_GAP, (chainCx, chainCy, i) => { @@ -689,10 +689,10 @@ export const Renderer = { } ctx.textAlign = "left"; }); - // ── punyaTimer + prarabdhaTimer — player के ऊपर, side-by-side ── + // ── punyaTimer + praarabdhaTimer — player के ऊपर, side-by-side ── { const hasPunya = pendingGoodKarma && !gameOver; - const hasPrarabdha = prarabdhaTimer > 0 && prarabdha > 0 && !gameOver; + const hasPraarabdha = praarabdhaTimer > 0 && praarabdha > 0 && !gameOver; // player के ऊपर position — chains/maya से दूर const HALF_GAP = 52; @@ -700,7 +700,7 @@ export const Renderer = { const PILL_W = 96; const PILL_H = 48; const PILL_R = 10; if (hasPunya) { - const timerCx = hasPrarabdha ? cx - HALF_GAP : cx; + const timerCx = hasPraarabdha ? cx - HALF_GAP : cx; const secondsLeft = Math.ceil(punyaTimer / 60); const pulse = (Math.sin(frameNow / 150) + 1) / 2; ctx.save(); @@ -727,9 +727,9 @@ export const Renderer = { ctx.restore(); } - if (hasPrarabdha) { + if (hasPraarabdha) { const timerCx = hasPunya ? cx + HALF_GAP : cx; - const secLeft = Math.ceil(prarabdhaTimer / 60); + const secLeft = Math.ceil(praarabdhaTimer / 60); const pulse = (Math.sin(frameNow / 150) + 1) / 2; ctx.save(); // pill background @@ -744,7 +744,7 @@ export const Renderer = { ctx.font = "700 9px 'Orbitron', sans-serif"; ctx.fillStyle = "rgba(200, 180, 255, 0.85)"; ctx.shadowBlur = 0; - ctx.fillText(t('hud.prarabdhaTimerLabel', { n: prarabdha }), timerCx, baseY - 13); + ctx.fillText(t('hud.praarabdhaTimerLabel', { n: praarabdha }), timerCx, baseY - 13); // countdown ctx.font = "900 " + (20 + pulse * 3) + "px 'Orbitron', sans-serif"; ctx.fillStyle = "#ffffff"; @@ -1049,12 +1049,12 @@ export const Renderer = { let innerOrbit = [ chetanaaJaagrita ? "👁️" : "😴", ashuvhaKarma >= 3 ? "⚫" : "☀️", - purnaSamarpana ? "🙌" : "🤲" + poornaSamarpana ? "🙌" : "🤲" ]; if (punaraJanmaCount > 0) innerOrbit.push("♻️"); if (shuvhaKarma > 0) innerOrbit.push("🌿"); if (ashuvhaKarma > 0) innerOrbit.push("🥀"); - if (prarabdha > 0) innerOrbit.push("📜"); + if (praarabdha > 0) innerOrbit.push("📜"); if (activeNaam > 0) innerOrbit.push("ॐ"); if (kripa > 0) innerOrbit.push("✋"); if (shankha > 0) innerOrbit.push("🐚"); @@ -1084,7 +1084,7 @@ export const Renderer = { ctx.save(); let extraGlow = (orbit.glowTimer && orbit.glowTimer > 0) ? (orbit.glowTimer / 60) * 22 : 0; // 📜 प्रारब्ध orbit — भोग-timer सक्रिय होने पर subtle pulse glow - if (o === 2 && prarabdhaTimer > 0) { + if (o === 2 && praarabdhaTimer > 0) { extraGlow += (Math.sin(frameNow / 300) * 0.5 + 0.5) * 12; } // extraGlow cap — over-bright orbit clutter रोकें diff --git a/src/shastra.js b/src/shaashtra.js similarity index 90% rename from src/shastra.js rename to src/shaashtra.js index 3cb989e..5eed493 100644 --- a/src/shastra.js +++ b/src/shaashtra.js @@ -1,6 +1,6 @@ /** * ============================================================ - * src/shastra.js — मोक्ष शास्त्र-ग्रंथ (Wisdom Scroll) + * src/shaashtra.js — मोक्ष शास्त्र-ग्रंथ (Wisdom Scroll) * ============================================================ * * ESC / BACK पर खुलने वाला दार्शनिक विवेचन — 3 pages। @@ -36,20 +36,20 @@ export const SHASTRA_SHLOKAS = { en: 'The fire of knowledge reduces all karmas to ashes.', }, }, - kathaRatha: { + kathoRatha: { text: 'आत्मानं रथिनं विद्धि शरीरं रथमेव तु।\nबुद्धिं तु सारथिं विद्धि मनः प्रग्रहमेव च॥', - credit: { hi: 'कठोपनिषद् १.३.३', en: 'Katha Upanishad 1.3.3' }, + credit: { hi: 'कठोपनिषद् १.३.३', en: 'Katho Upanishad 1.3.3' }, meaning: { hi: '', en: 'Know the Atman as the rider, the body as the chariot; know the Buddhi as the charioteer, and the mind as the reins.', }, }, - prarabdha: { + praarabdha: { text: 'प्रारब्धं भुज्यते एव', credit: { hi: '', en: '' }, meaning: { hi: '', - en: 'Prarabdha must indeed be undergone.', + en: 'Praarabdha must indeed be undergone.', }, }, tamaso: { @@ -79,10 +79,10 @@ const PAGE_1 = { title: '🌀 Cosmology 🌀', blocks: [ { type: 'para', text: 'Your journey through time and space is guided by a divine chariot. The chariot is the symbol of the path a soul travels toward Moksha, crossing the karmic winds of Samsara.' }, - { type: 'para', text: 'Every act you perform — Punya or Papa — bears fruit as a distortion of time (gati). Both Punya and Papa slow the chariot; both are bondage. Papa strikes the chariot directly (tremor and clouded vision), while Punya leads the mind astray through alluring temptation.' }, + { type: 'para', text: 'Every act you perform — Punya or Paapa — bears fruit as a distortion of time (gati). Both Punya and Paapa slow the chariot; both are bondage. Paapa strikes the chariot directly (tremor and clouded vision), while Punya leads the mind astray through alluring temptation.' }, { type: 'term', label: '🌬️ Swaansa (breath)', text: 'The symbol of remaining lifespan — the count of breaths left in this cycle of life.' }, { type: 'term', label: '⚖️ Cosmic horizon — the moment of decision', text: 'When Samaya reaches zero, that is the moment of decision. If at that instant the soul is wholly free of karma, Chetana is awakened (Samarpita ≥ 50), and full Naama-Samarpana (⬆️ / W) has been offered — only then is Moksha attained. Otherwise, Punarjanma follows.' }, - { type: 'term', label: '👁️ Chetana-Jagriti — karmic immunity', text: 'When Chetana awakens, the karmic effect of Maya falls to zero. Karma no longer binds an awakened soul.' }, + { type: 'term', label: '👁️ Chetana-Jaagriti — karmic immunity', text: 'When Chetana awakens, the karmic effect of Maya falls to zero. Karma no longer binds an awakened soul.' }, { type: 'shloka', id: 'gita437' }, ], }, @@ -119,7 +119,7 @@ const PAGE_2 = { { type: 'term', label: 'ॐ नाम', text: 'मोक्ष प्राप्ति का सबसे बड़ा सहायक।' }, { type: 'term', label: '✋ कृपा', text: '२० नाम पर १ कृपा। कृपा बढ़ने से पाप-माया घटती है।' }, { type: 'term', label: '📜 प्रारब्ध', text: 'प्रत्येक पुनर्जन्म पर — चाहे संचित कर्म कितना भी हो — प्रारब्ध केवल +1 बढ़ता है। समय को ×1.15 तेज़ करता है। अधिकतम 15। १० नाम से भोग-गति २× होती है।' }, - { type: 'shloka', id: 'prarabdha' }, + { type: 'shloka', id: 'praarabdha' }, { type: 'term', label: '👁️ चेतना-जागृति', text: '५० समर्पित पूर्ण होने पर चेतना जागती है — कर्म-माया का प्रभाव शून्य होता है। मोक्ष-पथ की प्रामाणिक शर्त।' }, ], }, @@ -132,29 +132,29 @@ const PAGE_2 = { { type: 'term', label: '🪷 Vairagya : ⬇️ / X | S', text: 'Refuse the lure of Punya — let go of attachment.' }, { type: 'term', label: '🌊 Pralaya : LB/L1 | Q', text: 'Invoke dissolution — abandon the chariot willingly.' }, { type: 'term', label: '♻️ Pure Punarjanma : LT/L2 | R', text: 'A new life with the entire karmic load set to zero.' }, - { type: 'term', label: '📖 Shastra : BACK | ESC', text: 'The door to Brahma-jnana. Time stands still.' }, + { type: 'term', label: '📖 Shaashtra : BACK | ESC', text: 'The door to Brahma-jnana. Time stands still.' }, { type: 'term', label: '⏸️ Stambhana (pause) : START | F', text: 'Hold the cosmic flow for a moment.' }, { type: 'term', label: '🐚 Shankha (quells the storm) : Y | GAMEPAD Y', text: 'Destroy the Maya-Chakravaata with the sound of the conch.' }, { type: 'note', text: 'The Yantra path — for when Naama is unavailable.', color: '#7dd3fc' }, - { type: 'term', label: '🪔 Jyoti (light of sight) : B | GAMEPAD B', text: 'Regain vision in the darkness of Papa.' }, - { type: 'note', text: 'Vision is obscured once Papa ≥ 3.', color: '#ffe932' }, + { type: 'term', label: '🪔 Jyoti (light of sight) : B | GAMEPAD B', text: 'Regain vision in the darkness of Paapa.' }, + { type: 'note', text: 'Vision is obscured once Paapa ≥ 3.', color: '#ffe932' }, // ── Final phase ── { type: 'heading', text: '🏔️ The Final Phase 🏔️' }, { type: 'term', label: '🙏 Samarpita (50)', text: 'Chetana awakens — the path toward Moksha opens.' }, - { type: 'term', label: '🌌 The Bhakti path', text: '1 Naama → burns Punya | 5 Naama → burns Papa | 10 Naama → burns Prarabdha.' }, - { type: 'term', label: 'ॐ 🙌 Purna-Samarpana : ⬆️ | RB/R1 | W', text: 'Surrender completely while inside the Bhakti path.' }, + { type: 'term', label: '🌌 The Bhakti path', text: '1 Naama → burns Punya | 5 Naama → burns Paapa | 10 Naama → burns Praarabdha.' }, + { type: 'term', label: 'ॐ 🙌 Poorna-Samarpana : ⬆️ | RB/R1 | W', text: 'Surrender completely while inside the Bhakti path.' }, { type: 'note', text: '⚠️ Only during the final phase (Samaya < 100s).', color: '#ff3232' }, // ── Fruits of karma ── { type: 'heading', text: '⏳ Fruits of Karma ⏳' }, { type: 'term', label: '🌿 Punya', text: 'Good deeds — pleasant, yet bondage.' }, - { type: 'term', label: '🥀 Papa', text: 'Ill deeds — a strike, and clouded vision.' }, + { type: 'term', label: '🥀 Paapa', text: 'Ill deeds — a strike, and clouded vision.' }, { type: 'term', label: 'ॐ Naama', text: 'The greatest aid in attaining Moksha.' }, - { type: 'term', label: '✋ Kripa', text: '1 Kripa for every 20 Naama. As Kripa grows, the Maya of Papa wanes.' }, - { type: 'term', label: '📜 Prarabdha', text: 'At every rebirth — however great the accumulated karma — Prarabdha rises by only +1. It hastens Samaya by ×1.15. Maximum 15. With 10 Naama the rate of enduring doubles.' }, - { type: 'shloka', id: 'prarabdha' }, - { type: 'term', label: '👁️ Chetana-Jagriti', text: 'On completing 50 Samarpita, Chetana awakens — the effect of karmic Maya falls to zero. The authentic condition of the path to Moksha.' }, + { type: 'term', label: '✋ Kripa', text: '1 Kripa for every 20 Naama. As Kripa grows, the Maya of Paapa wanes.' }, + { type: 'term', label: '📜 Praarabdha', text: 'At every rebirth — however great the accumulated karma — Praarabdha rises by only +1. It hastens Samaya by ×1.15. Maximum 15. With 10 Naama the rate of enduring doubles.' }, + { type: 'shloka', id: 'praarabdha' }, + { type: 'term', label: '👁️ Chetana-Jaagriti', text: 'On completing 50 Samarpita, Chetana awakens — the effect of karmic Maya falls to zero. The authentic condition of the path to Moksha.' }, ], }, }; @@ -163,7 +163,7 @@ const PAGE_3 = { hi: { title: '👁️ प्रतीकवाद 👁️', blocks: [ - { type: 'shloka', id: 'kathaRatha' }, + { type: 'shloka', id: 'kathoRatha' }, { type: 'term', label: '🐎 छह घोड़े (छह इंद्रियाँ)', text: 'स्वचालित रूप से सांसारिक वस्तुओं की ओर खींचते हैं।' }, { type: 'term', label: '🪢 लगाम (मन)', text: 'षडिन्द्रिय संतुलन की ओर यात्रा करता सूक्ष्म तत्त्व।' }, { type: 'term', label: '☸️ रथ (शरीर)', text: 'आत्मा को ले जाने वाला स्थूल रूप।' }, @@ -179,16 +179,16 @@ const PAGE_3 = { en: { title: '👁️ Symbolism 👁️', blocks: [ - { type: 'shloka', id: 'kathaRatha' }, + { type: 'shloka', id: 'kathoRatha' }, { type: 'term', label: '🐎 Six horses (the six senses)', text: 'They pull of their own accord toward worldly objects.' }, { type: 'term', label: '🪢 Reins (the mind)', text: 'The subtle element travelling toward balance among the six senses.' }, { type: 'term', label: '☸️ Chariot (the body)', text: 'The gross form that carries the soul.' }, { type: 'term', label: '🪈 Charioteer (Buddhi)', text: 'The active charioteer holding the reins of the senses.' }, { type: 'term', label: '🪔 Passenger (Atman)', text: 'The divine conscious energy seated in the causal body.' }, - { type: 'term', label: 'ॐ Naama (self-remembrance)', text: 'The pure energy that burns Prarabdha to ash.' }, + { type: 'term', label: 'ॐ Naama (self-remembrance)', text: 'The pure energy that burns Praarabdha to ash.' }, { type: 'term', label: '🌬️ Swaansa (remaining lifespan)', text: 'Every breath carries you nearer the last.' }, { type: 'term', label: '🐚 Shankha (the Yantra path)', text: 'When Naama-Japa is not possible, the sound of the conch pierces the Maya-Chakravaata — the delusion of the world destroyed by the power of Yantra.' }, - { type: 'term', label: '🪔 Jyoti (the path of light)', text: 'In the darkness of Papa, Jyoti restores sight.' }, + { type: 'term', label: '🪔 Jyoti (the path of light)', text: 'In the darkness of Paapa, Jyoti restores sight.' }, { type: 'shloka', id: 'tamaso' }, ], }, @@ -210,13 +210,13 @@ function escapeHtml(s) { } /** - * renderShastraPage — एक page का HTML बनाएँ। + * renderShaashtraPage — एक page का HTML बनाएँ। * * @param {number} pageIndex — 0-based * @param {string} lang — 'hi' | 'en' * @returns {string} — HTML string */ -export function renderShastraPage(pageIndex, lang) { +export function renderShaashtraPage(pageIndex, lang) { const page = SHASTRA_PAGES[pageIndex]?.[lang] ?? SHASTRA_PAGES[pageIndex]?.hi; // fallback if (!page) return ''; diff --git a/src/state.js b/src/state.js index e91569e..262cc76 100644 --- a/src/state.js +++ b/src/state.js @@ -130,16 +130,16 @@ export const StateMixin = { this._updateStatWithPulse(this._UI.paap, 'paap', this.ashuvhaKarma, '🥀'); - // 📜 prarabdha — bhog-timer active होने पर live countdown दिखे - if (this._UI?.prarabdha) { - const bhogSec = this.prarabdhaTimer > 0 - ? ` ⏱${Math.ceil(this.prarabdhaTimer / 60)}s` : ''; - const newDisplay = `📜 ${this.prarabdha}${bhogSec}`; - if (this._UI.prarabdha.textContent !== newDisplay) { - this._UI.prarabdha.textContent = newDisplay; - this._uiScales.prarabdha = 1.15; - this._uiGlows.prarabdha = 1.0; - this._oldStats.prarabdha = this.prarabdha; + // 📜 praarabdha — bhog-timer active होने पर live countdown दिखे + if (this._UI?.praarabdha) { + const bhogSec = this.praarabdhaTimer > 0 + ? ` ⏱${Math.ceil(this.praarabdhaTimer / 60)}s` : ''; + const newDisplay = `📜 ${this.praarabdha}${bhogSec}`; + if (this._UI.praarabdha.textContent !== newDisplay) { + this._UI.praarabdha.textContent = newDisplay; + this._uiScales.praarabdha = 1.15; + this._uiGlows.praarabdha = 1.0; + this._oldStats.praarabdha = this.praarabdha; } } @@ -154,14 +154,14 @@ export const StateMixin = { this.chetanaaJaagrita ? "👁️" : "😴", ""); this._updateStatWithPulse(this._UI.drishti, 'drishti', this.ashuvhaKarma >= 3 ? "⚫" : "☀️", ""); - this._updateStatWithPulse(this._UI.purnaSamarpana, 'purnaSamarpana', - this.purnaSamarpana ? "🙌" : "🤲", ""); + this._updateStatWithPulse(this._UI.poornaSamarpana, 'poornaSamarpana', + this.poornaSamarpana ? "🙌" : "🤲", ""); }, /** HUD scale/glow animation एक frame advance करें */ _updateHUDAnimations(dt) { const uiKeys = [ - 'purnaSamarpana', 'naama', 'punya', 'paap', 'prarabdha', + 'poornaSamarpana', 'naama', 'punya', 'paap', 'praarabdha', 'samarpita', 'punaraJanma', 'gatee', 'chetana', 'shankha', 'drishti', 'jyoti', 'kripa', ]; diff --git a/src/touch.js b/src/touch.js index ea8d6d6..86e563c 100644 --- a/src/touch.js +++ b/src/touch.js @@ -118,7 +118,7 @@ export class TouchControls { */ /** * किसी कारण से controls block करें (hide)। - * @param {string} reason — 'start' | 'tutorial' | 'shastra' | 'viraama' | 'end' + * @param {string} reason — 'start' | 'tutorial' | 'shaashtra' | 'viraama' | 'end' */ block(reason) { if (!this._active) return; diff --git a/src/tutorial.js b/src/tutorial.js index a0c5abf..fac8593 100644 --- a/src/tutorial.js +++ b/src/tutorial.js @@ -18,7 +18,7 @@ * 1: maya — naama माया पहचानो * 2: jaapa — नाम-जाप करो (ENTER) * 3: tunnel — भक्ति-मार्ग में जाओ - * 4: prarabdha — प्रारब्ध ज्ञान (info card, dismiss = complete) + * 4: praarabdha — प्रारब्ध ज्ञान (info card, dismiss = complete) * * ── main.js में उपयोग ──────────────────────────────────────── * import { TutorialManager } from './tutorial.js'; @@ -77,7 +77,7 @@ const TUTORIAL_STEPS = [ dismissToComplete: false, }, { - id: 'prarabdha', + id: 'praarabdha', shloka: 'भोगेन क्षीयते पापं, तपसा क्षीयते मलः।', forceSpawn: null, dismissToComplete: true, // dismiss = tutorial complete @@ -233,7 +233,7 @@ export class TutorialManager { break; } - case 'prarabdha': + case 'praarabdha': // dismiss-only step — checkCompletion यहाँ कभी नहीं चलता // (_cardVisible = true रहेगा dismiss तक) break; diff --git a/style.css b/style.css index 8b32283..415a06e 100644 --- a/style.css +++ b/style.css @@ -251,7 +251,7 @@ button.hud-icon-btn:hover { #naama { color: #ffffff; } /* ॐ नाम — शुद्ध श्वेत */ #punya { color: #32ff80; } /* 🌿 पुण्य — दिव्य हरा */ #paap { color: #ff2244; } /* 🥀 पाप — रक्त-वर्ण */ -#prarabdha { color: #a78bfa; } /* 📜 प्रारब्ध — नील-बैंगनी */ +#praarabdha { color: #a78bfa; } /* 📜 प्रारब्ध — नील-बैंगनी */ #samarpita { color: #fb923c; } /* 🙏 समर्पित — नारंगी */ #punaraJanma { color: #f87171; } /* ♻️ जन्म — गुलाबी-लाल */ #kripa { color: #ffe9a8; } /* ✋ कृपा — सोनारंग */ @@ -259,7 +259,7 @@ button.hud-icon-btn:hover { #jyoti { color: #ffe932; } /* 🪔 ज्योति — सुवर्ण-पीत */ #chetana { color: #2dd4bf; } /* 👁️ चेतना — वैदूर्य-हरा */ #drishti { color: #facc15; } /* ☀️ दृष्टि — तेज-पीत */ -#purnaSamarpana { color: #e879f9; } /* 🙌 पूर्ण — दिव्य-नील */ +#poornaSamarpana { color: #e879f9; } /* 🙌 पूर्ण — दिव्य-नील */ /* ====================== PAUSE (VIRAAMA) OVERLAY ====================== */ #viraama-overlay { @@ -315,7 +315,7 @@ button.hud-icon-btn:hover { } /* ====================== SHASTRA OVERLAY ====================== */ -#shastra-overlay { +#shaashtra-overlay { position: absolute; top: 0; left: 0; @@ -332,7 +332,7 @@ button.hud-icon-btn:hover { /* z-index:20 था → start-screen (z-index:50) के पीछे छुप जाता था — अब सभी overlays से ऊँचा */ } -.shastra-content { +.shaashtra-content { position: relative; width: 100%; height: 100%; @@ -352,7 +352,7 @@ button.hud-icon-btn:hover { } /* शास्त्र बंद करने का स्पष्ट बटन */ -#shastra-close-btn { +#shaashtra-close-btn { position: absolute; top: 14px; right: 16px; @@ -370,18 +370,18 @@ button.hud-icon-btn:hover { z-index: 1; } -#shastra-close-btn:hover { +#shaashtra-close-btn:hover { background: rgba(255, 120, 30, 0.28); box-shadow: 0 0 12px rgba(255, 120, 30, 0.5); } -.shastra-header { +.shaashtra-header { border-bottom: 1px solid rgba(255, 136, 0, 0.3); padding-bottom: 10px; margin-bottom: 15px; } -.shastra-header h2 { +.shaashtra-header h2 { font-family: 'Orbitron', sans-serif; font-size: 32px; margin: 0; @@ -389,13 +389,13 @@ button.hud-icon-btn:hover { text-shadow: 0 0 10px rgba(255, 215, 0, 0.7); } -.shastra-header p { +.shaashtra-header p { margin: 5px 0 0 0; color: #ccc; font-style: italic; } -.shastra-body { +.shaashtra-body { flex: 1; overflow-y: auto; padding: 10px 20px; @@ -409,20 +409,20 @@ button.hud-icon-btn:hover { scrollbar-width: none; } -.shastra-body::-webkit-scrollbar { +.shaashtra-body::-webkit-scrollbar { display: none; } -.shastra-page { +.shaashtra-page { display: none; animation: fadeIn 0.4s ease-in-out; } -.shastra-page.active { +.shaashtra-page.active { display: block; } -.shastra-page h3 { +.shaashtra-page h3 { font-family: 'Orbitron', sans-serif; color: #ffa600; border-bottom: 1px solid rgba(255, 255, 255, 0.1); @@ -430,11 +430,11 @@ button.hud-icon-btn:hover { margin-bottom: 15px; } -.shastra-page p strong { +.shaashtra-page p strong { color: #ffa600; } -.shastra-footer { +.shaashtra-footer { display: flex; justify-content: space-between; align-items: center; @@ -442,7 +442,7 @@ button.hud-icon-btn:hover { border-top: 1px solid rgba(255, 136, 0, 0.3); } -.shastra-footer button { +.shaashtra-footer button { background: rgba(255, 136, 0, 0.15); color: #ffa600; font-family: 'Orbitron', sans-serif; @@ -456,7 +456,7 @@ button.hud-icon-btn:hover { text-align: center; } -.shastra-footer button:hover { +.shaashtra-footer button:hover { background: rgba(255, 120, 30, 0.25); filter: drop-shadow(0 0 8px rgba(255, 120, 30, 0.6)); }