சிறந்த ரோக்லைக்குகள் (roguelikes) உங்களை வெறும் கொல்வதில்லை. அவை நீங்கள் இறக்க வேண்டும் என்று கூடத் தூண்டும்.

இது விசித்திரமாகத் தோன்றலாம், ஆனால் நள்ளிரவில் ஒரு விளையாட்டைத் தோற்றுப்போய்விட்டு, 12:03-க்கு மீண்டும் ஒரு புதிய விளையாட்டைத் தொடங்கிய எவருக்கும் அந்த உணர்வு தெரியும். மரணம் வலிக்கிறது. உங்கள் ஆரோக்கியம் (health) பூஜ்ஜியத்திற்குத் தள்ளப்படுகிறது. தோல்வித் திரை உங்கள் கண்களுக்கு முன்னால் விரிகிறது. இருப்பினும், உங்கள் விரல் ஏற்கனவே 'play' பொத்தானின் மேல் காத்திருக்கிறது. கடந்த இருபது நிமிடங்களில் நடந்தவை ஏதோ ஒரு வகையில் முக்கியத்துவம் வாய்ந்தவை, அதனால் விளையாட்டை அப்படியே விட்டுவிட உங்களால் முடிவதில்லை.

இதுதான் "இன்னொரு முறை மட்டும்" (one more run) சுழற்சி, இது தற்செயலானது அல்ல. இது திட்டமிடப்பட்டது. நீங்கள் ஒரு ரோக்லைக்கை அல்லது 'permadeath' கொண்ட எந்தவொரு விளையாட்டையும் உருவாக்குகிறீர்கள் என்றால், இரண்டு முரண்பட்ட சக்திகளைச் சமநிலைப்படுத்துவதே உங்கள் முழு வேலையாகும். ஒரு வீரர் பதற்றத்தை உணரப் போதுமான அளவு தோற்க வேண்டும். அதே சமயம், நம்பிக்கையைத் தக்கவைக்கப் போதுமான அளவு முன்னேற்றத்தையும் வைத்திருக்க வேண்டும்.

தோல்வியின் நாணயம்

எனது சமீபத்தியத் திட்டமான Neon Survivor-இல், நான் அதே போன்ற பதற்றத்தை உருவாக்க விரும்பினேன். வீரர் இறக்கும்போது, அந்த விளையாட்டின் போது சேகரிக்கப்பட்ட அனைத்தும் மறைந்துவிடும், ஒன்று தவிர: தங்கம் (gold). அந்தத் தங்கம் தானாகவே சேமிக்கப்படும் (banked). மெனுவிற்குத் திரும்பியதும், அதை நிரந்தர மேம்பாடுகளுக்காக (permanent upgrades) அவர்கள் செலவிடலாம். பின்னர் அவர்கள் மீண்டும் விளையாட்டிற்குள் நுழையும்போது, முன்பை விடச் சற்று வலிமையாக இருப்பார்கள்.

இந்த எளிய சுழற்சியே முழு விளையாட்டையும் இயக்குகிறது. இது இல்லையென்றால், மரணம் என்பது ஒரு முற்றுப்புள்ளி (full stop). கடந்த விளையாட்டில் எதுவும் கிடைக்காததால் வீரர் விளையாட்டை விட்டு விலகிவிடுவார். இது இருந்தால், மரணம் என்பது ஒரு கமா (comma) போன்றது. அந்த விளையாட்டு ஒரு சேகரிப்புப் பயணமாக (farming trip) மாறுகிறது. இழப்பு வலிக்கிறது, ஆனால் அது நாளைய முன்னேற்றத்திற்கான முதலீடாகவும் அமைகிறது.

இதன் ரகசியம் எளிமையானது. மற்ற அனைத்தும் தொலைந்து போனாலும், ஏதோ ஒன்றை நீங்கள் தக்கவைத்துக் கொள்ள வேண்டும். சவாலைச் சிதைக்காமல், நீங்கள் தக்கவைத்துக் கொள்ளும் அந்த விஷயம் முக்கியத்துவம் வாய்ந்ததாக இருப்பதை உறுதி செய்வதே கடினமான காரியம். மேம்பாடுகள் (upgrades) மிகவும் பலவீனமாக இருந்தால், வீரர் அதைப் பொருட்படுத்த மாட்டார். அவை மிகவும் வலிமையாக இருந்தால், விளையாட்டு தானாகவே நடந்துவிடும். இரண்டு வழிகளிலும் இந்தச் சுழற்சி உடைந்துவிடும்.

இரண்டு கடிகாரங்கள், பூஜ்ஜிய குழப்பம்

இதைச் சரியாக உருவாக்க, நான் இரண்டு தனித்தனி காலவரிசைகளை (timelines) நிர்வகிக்க வேண்டியிருந்தது.

'Run Clock' நீங்கள் விளையாட்டைத் தொடங்கும் ஒவ்வொரு முறையும் ரீசெட் (reset) செய்யப்படும். இது ஆரோக்கியம், தற்போதைய மதிப்பெண், எதிரிகளின் எண்ணிக்கை மற்றும் அந்த அமர்வின் போது பெறப்பட்ட தற்காலிக சக்திகள் (power-ups) ஆகியவற்றைத் தொடர்ந்து கண்காணிக்கும். கதாபாத்திரம் இறக்கும்போது, இந்த கடிகாரம் மீண்டும் பூஜ்ஜியத்திற்குத் திரும்பும்.

'Meta Clock' ஒருபோதும் ரீசெட் செய்யப்படாது. இது ஒவ்வொரு முயற்சியிலும் ஈட்டப்பட்ட மொத்தத் தங்கம், எட்டப்பட்ட மிக உயர்ந்த நிலை மற்றும் வாங்கப்பட்ட ஒவ்வொரு நிரந்தர மேம்பாட்டையும் வைத்திருக்கும். பிரவுசர் எத்தனை முறை ரீஃப்ரெஷ் (refresh) செய்யப்பட்டாலும் இந்த கடிகாரம் ஓடிக்கொண்டே இருக்கும்.

இவை இரண்டையும் ஒன்றாகக் கலக்கும்போது, கண்டறிவதற்கு கடினமான மற்றும் சரிசெய்வதற்குத் துன்பமான பிழைகள் (bugs) உருவாகின்றன. ஒரு வழக்கமான 'scene reset' செய்யும் போது, ஒரு கிளீனப் ஃபங்ஷன் (cleanup function) தவறான தரவுச் சேமிப்பகத்தைத் (data store) தொட்டதால், வீரரின் முன்னேற்றத்தை டெவலப்பர்கள் தவறுதலாக அழிப்பதைக் கண்டிருக்கிறேன். 'Meta Clock' தரவு ஆவியாகிவிடும். வீரர் பூஜ்ஜியத் தங்கம் மற்றும் பூஜ்ஜிய மேம்பாடுகளுடன் தொடங்குவார். அந்தத் தருணத்தில், உங்களுக்கும் உங்கள் வீரருக்கும் இடையிலான உறவு உடைந்துவிடும். அவர்கள் ஒரு புதிய விளையாட்டைத் தொடங்கவில்லை; அவர்கள் ஒரு புதிய பகையைத் தொடங்குகிறார்கள்.

கடிகாரங்களைத் தனித்தனியாக வைத்திருப்பது வெறும் பாணித் தேர்வு (style choice) மட்டுமல்ல. அது ஒரு உயிர்வாழும் உத்தி (survival strategy).

Phaser v4 இந்தத் தனிப்பிரிவை எவ்வாறு கையாளுகிறது

நான் Neon Survivor-ஐ Phaser v4-இல் உருவாக்கினேன், இது இந்தப் பிரச்சனைக்கு இரண்டு குறிப்பிட்ட கருவிகளை வழங்குகிறது.

Registry தற்போதைய அமர்விற்கான நேரடித் தரவை நினைவகத்தில் (memory) வைத்திருக்கும். இது வேகமானது. இது எளிமையானது. ஆனால் வீரர் பக்கத்தைப் புதுப்பித்தவுடன் இது மறைந்துவிடும்.

LocalStorage தரவை பிரவுசரிலேயே சேமிக்கிறது. இது டேப் (tab) மூடுதல், பிரவுசர் மறுதொடக்கம் மற்றும் மின்சாரத் தடங்கல்களையும் தாங்கி நிற்கும். இது மெதுவானது மற்றும் நம்பகத்தன்மை குறைந்தது. சேமிப்பு அளவு (storage quotas) நிறைந்தால் பிரவுசர்கள் இதைத் தடுக்கலாம் அல்லது அழிக்கலாம்.

எனது வடிவமைப்புத் தேர்வு மிகவும் கண்டிப்பானது. விளையாட்டு நடக்கும் போது Registry மட்டுமே உண்மையான ஆதாரமாக (source of truth) இருக்கும். விளையாட்டு அதிலிருந்து படிக்கிறது, அதில் எழுதுகிறது மற்றும் அதை முழுமையாக நம்புகிறது. LocalStorage ஒரு இணை-ஆசிரியராக (co-author) செயல்படாது. அது ஒரு கண்ணாடியாக (mirror) மட்டுமே செயல்படுகிறது.

இதன் செயல்முறை இதோ: விளையாட்டு ஒரு மேம்பாட்டுப் பதிவை (upgrade purchase) Registry-இல் எழுதுகிறது. ஒரு மேலாளர் வகுப்பு (manager class) Registry-ஐக் கண்காணிக்கும். பொருத்தமான நேரத்தில், அந்த மேலாளர் Registry தரவை LocalStorage-க்கு பிரதிபலிக்கிறது (mirrors). பிரவுசர் எழுதுவதைத் தடுத்தாலும், விளையாட்டுத் தடுமாறாது. சேமிப்புத் தோல்வியடைந்தாலும், தற்போதைய அமர்வு சரியாக இயங்கும். வீரர் அதே நொடியில் டேப்பை மூடினால் மட்டுமே முன்னேற்றம் இழக்கப்படலாம், ஆனால் அமர்வு ஒருபோதும் செயலிழக்காது (crash).

இந்த முறை ஒரு நுட்பமான பேரழிவைத் தடுக்கிறது. ஒவ்வொரு அமைப்பும் நேரடியாக LocalStorage-இல் எழுத அனுமதித்தால், நீங்கள் ஒரு பலவீனமான API-யைச் சார்ந்திருக்கும் சூழலை உருவாக்குவீர்கள். தனியுரிமை அமைப்புகளை (privacy settings) அதிகமாக வைத்திருக்கும் அல்லது சேமிப்புத் திறன் குறைவாக உள்ள ஒரு வீரரின் விளையாட்டு, பின்னணியில் இயங்கும் ஒரு செயல்பாடு புள்ளிவிவரங்களைச் சேமிக்க முயலும்போது, போர்க்களத்தில் மெதுவாவோ அல்லது முடங்கியோ போகலாம். Registry-ஐ மட்டுமே உண்மையான ஆதாரமாக மாற்றுவதன் மூலம், நீங்கள் வேகமான செயல்பாட்டையும் கட்டுப்படுத்தப்பட்ட அபாயத்தையும் உறுதி செய்கிறீர்கள்.

குறியீட்டை (Code) சுதந்திரமாக விடவும்

அமைப்புகளைத் தனித்தனியாகப் பிரிக்க (decouple) நான் நிகழ்வுகளையும் (events) பயன்படுத்தினேன். ஒரு விளையாட்டு முடிந்ததும், GameScene தனது சொந்த இறுதிச் சடங்குகளைச் செய்யாது. அது ஒரு சேமிப்புச் செயல்பாட்டை (save function) அழைக்காது. அது ஒரு சேமிப்பு கருவியைத் (storage utility) இறக்குமதி செய்யாது. அது தொடர்புடைய தரவுகளுடன் ஒரு "run-ended" நிகழ்வை (event) வெளியிடும் (emit).

ஒரு தனிப்பட்ட listener கணக்கு பராமரிப்பைக் கையாள்கிறது. இது நிகழ்வைப் (event) பெற்று, Meta Clock-ஐப் புதுப்பித்து, புதிய மொத்தத் தொகையை LocalStorage-க்கு பிரதிபலிக்க மேலாளரிடம் (manager) கூறுகிறது.

இந்தத் தனிமைப்படுத்தல் உடனடியாகப் பலன் அளிக்கிறது. சேமிப்பு அமைப்பை (save system) தொடாமலேயே, முழு GameScene-ஐயும் மாற்றி எழுதவோ, வீரர் கதாபாத்திரத்தை மாற்றவோ, கேமரா கோணத்தை மாற்றவோ அல்லது விளையாட்டின் வகையை survival-லிருந்து bullet hell-க்கு மாற்றவோ என்னால் முடியும். இந்த அமைப்புகள் ஒன்றையொன்று சார்ந்து இருக்காது. அவை நேரடி செயல் அழைப்புகளுக்குப் (direct function calls) பதிலாக நிகழ்வுகள் (events) மூலம் தொடர்பு கொள்கின்றன. இதன் பொருள் குறைவான merge conflicts, குறைவான பிழைகள் (bugs) மற்றும் ஆறு மாதங்களுக்குப் பிறகு குழப்பமான (spaghetti) குறியீட்டுத் தொகுப்பாக (codebase) மாறாத ஒரு அமைப்பு.

விளையாட்டின் போக்கையே மாற்றும் மேம்படுத்தல்கள் (Upgrades)

தொழில்நுட்ப முதுகெலும்பு இருப்பது ஒரு விஷயமென்றால், வெகுமதிகள் (rewards) வெறும் எண்களாக (spreadsheet போல) இருந்தால் அது பயனற்றது. மேம்படுத்தல்கள் (upgrades) விளையாடும்போது உண்மையில் எப்படி உணரப்படுகின்றன என்பதில் நான் அதிக நேரத்தைச் செலவிட்டேன்.

சில மேம்படுத்தல்கள் பாதுகாப்பானவை. கூடுதல் நகரும் வேகம், கூடுதல் ஆரோக்கியம், வேகமான reload போன்றவை. இவை வீரருக்குத் தவறு செய்ய அதிக வாய்ப்பை வழங்குகின்றன. இவை ஆறுதலாக இருக்கும். இவை விளையாட்டின் விதிகளை மாற்றாமல், விளையாட்டின் கடினத்தன்மையைக் குறைக்கின்றன.

மற்ற மேம்படுத்தல்கள் விதிமுறைகளையே முற்றிலும் மாற்றி எழுதுகின்றன. Neon Survivor-இல், நான் "Piercing Rounds"-ஐச் சேர்த்தேன். இந்த மேம்படுத்தலுக்கு முன்பு, ஒரு குண்டு முதல் எதிரியைத் தாக்கியவுடன் நின்றுவிடும். மேம்படுத்தலுக்குப் பிறகு, அது எதிரிகளை ஊடுருவிச் சென்று, ஒரே ஒரு சுட்டில் முழு வரிசையையும் அழிக்கக்கூடும்.

இந்த வித்தியாசம் வியக்கத்தக்கது. வேகம் மற்றும் ஆரோக்கியம் உங்களை நீண்ட நேரம் உயிர்வாழச் செய்யலாம், ஆனால் Piercing Rounds நீங்கள் விளையாடும் முறையையே மாற்றுகிறது. நீங்கள் எதிரிகளை வரிசைப்படுத்தத் தொடங்குவீர்கள். ஓரங்களில் சுற்றிக்கொண்டிருக்காமல் (kiting), மையப்பகுதியைக் கடந்து செல்லத் தொடங்குவீர்கள். விளையாட்டின் முடிவெடுக்கும் பரப்பு (decision space) விரிவடைகிறது.

சிறந்த முன்னேற்றம் (progression) என்பது வீரரின் எண்களை அதிகரிப்பது மட்டுமல்ல, அவர்களின் முடிவுகளையும் மாற்ற வேண்டும். ஒவ்வொரு மேம்படுத்தலும் வெறும் சதவீத உயர்வு மட்டுமே என்றால், வீரர் அதன் விளக்கங்களைப் படிப்பதை நிறுத்திவிடுவார். அவர்கள் கிளிக் செய்வார்கள், மேம்படுத்துவார்கள், பிறகு மறந்துவிடுவார்கள். ஒரு மேம்படுத்தல் அவர்களைத் தங்கள் வியூகத்தை மறுபரிசீலனை செய்யத் தூண்டினால், அவர்கள் அதை நினைவில் கொள்வார்கள். அதைப்பற்றிப் பேசுவார்கள். விளையாட்டைத் தலைகீழாக மாற்றக்கூடிய வேறு என்ன இருக்கிறது என்று பார்க்க மீண்டும் வருவார்கள்.

உண்மையான பலன்

"one more run" சுழற்சி என்பது ஒரு தனி அமைப்பு அல்ல. இது இழப்பு மற்றும் லாபத்திற்கு இடையிலான ஒரு உறவு, இது தூய்மையான கட்டமைப்பு (clean architecture) மற்றும் அர்த்தமுள்ள வெகுமதிகளின் (meaningful rewards) அடிப்படையில் கட்டமைக்கப்பட்டுள்ளது.

இரண்டு தனித்த காலவரிசைகளை (timelines) உருவாக்குங்கள் மற்றும் Meta Clock உங்கள் வீரர்களின் நம்பிக்கையைப் பாதுகாப்பது போல அதைப் பாதுகாக்கவும், ஏனெனில் அது உண்மையில் அவர்களின் நம்பிக்கையைப் பெறுகிறது. நேரடித் தரவை (live data) வேகமாகவும், நிலையான தரவை (persistent data) பாதுகாப்பாகவும் வைத்திருக்க உங்கள் எஞ்சின் கருவிகளைப் பயன்படுத்துங்கள். பயமின்றி மீண்டும் மீண்டும் மாற்றங்களைச் செய்ய (iterate), உங்கள் காட்சிகளை (scenes) உங்கள் சேமிப்பகத்திலிருந்து (storage) தனித்தனியாகப் பிரியுங்கள் (decouple). மேலும் நீங்கள் மேம்படுத்தல்களை வடிவமைக்கும்போது, அவை வீரருக்கு அதிக நேரத்தைத் தருகின்றனவா அல்லது அதிக சுவாரஸ்யமான தேர்வுகளைத் தருகின்றனவா என்று கேளுங்கள்.

இதைச் சரியாகச் செய்துவிட்டால், உங்கள் வீரர்கள் மரணத்தைத் தாங்கிக்கொள்வது மட்டுமல்லாமல், அதையே சார்ந்திருப்பார்கள். ஒவ்வொரு முறையும் விளையாடுவது அடுத்த முறைக்கான ஒரு முன்பணமாக (down payment) மாறும். விளையாட்டு என்பது தொடர்ச்சியான மறுதொடக்கங்களின் தொகுப்பாக இல்லாமல், ஒரு தொடர்ச்சியான ஏற்றமாக மாறும்.