எனது கேம் என்ஜினிற்காக கோரூட்டின்களை (Coroutines) உருவாக்கினேன், ஆனால் அவற்றைப் பயன்படுத்தவில்லை

எனது கேம் என்ஜினிற்காக ஒரு ஜெனரேட்டர் கோரூட்டின் (generator coroutine) அமைப்பை உருவாக்கினேன். அதில் 122 வரிகள் குறியீடும் (code), 12 சோதனைகளும் (tests) இருந்தன. இது 'callback hell' சிக்கலைத் தீர்த்தது. இது ஸ்கிரிப்ட்களை நேர்க்கோடுகள் போலத் தோன்றச் செய்தது.

பின்னர் எனது கேம் லாஜிக்கிற்கு (game logic) அதைப் பயன்படுத்தாமல் இருக்க முடிவு செய்தேன். அதற்குப் பதிலாக ஒரு Finite State Machine (FSM)-ஐப் பயன்படுத்தினேன்.

அதற்கான காரணங்கள் இதோ.

நிகழ்நேர விளையாட்டுகளில் (real-time games) ஜெனரேட்டர்களுடன் இருக்கும் இரண்டு மிகப்பெரிய சிக்கல்களைப் பெரும்பாலான பயிற்சிகள் (tutorials) புறக்கணிக்கின்றன: நினைவகம் (memory) மற்றும் சேமிப்பு (saving).

  1. நினைவக அழுத்தம் (Memory Pressure) ஒரு ஜெனரேட்டரில் நீங்கள் ஒவ்வொரு முறையும் .next() என்று அழைக்கும்போது, ஜாவாஸ்கிரிப்ட் என்ஜின் ஒரு புதிய ஆப்ஜெக்ட்டை (object) உருவாக்குகிறது. இந்த ஆப்ஜெக்ட் தற்போதைய மதிப்பு மற்றும் நிலையை (status) கொண்டுள்ளது.

60 FPS வேகத்தில் இயங்கும் ஒரு கேம் லூப்பில் (game loop), இது தொடர்ச்சியான 'garbage collection' அழுத்தத்தை உருவாக்குகிறது. செயல்திறனை (performance) நிலையாக வைத்திருக்க எனது என்ஜின் 'zero-allocation' விதியைப் பின்பற்றுகிறது. ஜெனரேட்டர்கள் அந்த விதியை மீறுகின்றன. அவை ஒவ்வொரு பிரேமிலும் (frame) சிறிய ஆப்ஜெக்ட்களின் ஒரு தொடரையே உருவாக்குகின்றன.

  1. சீரியலைசேஷன் சிக்கல் (The Serialization Problem) ஒரு கேம் சேமிக்கப்படவும் (save) மற்றும் ஏற்றப்படவும் (load) வேண்டும். தற்போதைய கேம் நிலையை (game state) தரவாகவும் (data), மீண்டும் பழைய நிலைக்குத் திருப்பவும் நீங்கள் தேவைப்படும்.

நிறுத்தப்பட்ட (paused) ஒரு ஜெனரேட்டரை உங்களால் சீரியலைஸ் (serialize) செய்ய முடியாது. அதன் நிலை, நீங்கள் அணுக முடியாத என்ஜினின் உள் ஸ்லாட்களில் (internal engine slots) உள்ளது. நீங்கள் அதைச் சேமிக்க முயன்றால், ஒரு காலியான ஆப்ஜெக்ட் அல்லது பிழை (error) கிடைக்கும்.

ஒரு Finite State Machine வேறுபட்டது. அதன் நிலை என்பது ஒரு காம்பொனென்ட்டில் (component) உள்ள ஒரு ஸ்டிரிங் (string) மட்டுமே.

  • சேமிக்க: அந்த ஸ்டிரிங்கை டிஸ்க்கில் (disk) எழுதவும்.
  • ஏற்ற: அந்த ஸ்டிரிங்கை வாசித்து, FSM அங்கிருந்து தொடங்குமாறு கூறவும்.

ஒரு தொழில்முறை கேமிற்குத் தேவையான இரண்டு முக்கியமான விஷயங்களான செயல்திறன் (performance) மற்றும் நிலைத்தன்மை (persistence) ஆகியவற்றை FSM கையாளுவதால் அது வெற்றி பெற்றது.

எப்படித் தேர்ந்தெடுப்பது:

லாஜிக் முக்கிய பிரேம் லூப்பிற்குள் (main frame loop) உள்ளதா?

  • இல்லை: ஒரு ஜெனரேட்டர் கோரூட்டினைப் பயன்படுத்தவும். அசெட்களை (assets) ஏற்றுவது அல்லது ஆன்போர்டிங் (onboarding) போன்ற ஒருமுறை நடக்கும் செயல்பாடுகளுக்கு அவை சிறந்தவை.
  • ஆம்: அடுத்த கேள்வியைக் கேட்கவும்.

நிலை (state) சேமிப்பிற்குப் பிறகும் தொடர வேண்டுமா?

  • ஆம்: ஒரு Finite State Machine-ஐப் பயன்படுத்தவும்.
  • இல்லை: அடுத்த கேள்வியைக் கேட்கவும்.

ஒரே நேரத்தில் பல வரிசைகளை (sequences) இயக்குகிறீர்களா?

  • ஆம்: ஒரு Finite State Machine-ஐப் பயன்படுத்தவும்.
  • இல்லை: ஒரு ஜெனரேட்டர் கோரூட்டினைப் பயன்படுத்தவும்.

ஜெனரேட்டர்கள் ஒரு தவறு அல்ல. அவை 'hot path'-க்குத் தவறான கருவி மட்டுமே. அவற்றை async glue-க்காகப் பயன்படுத்தவும், ஆனால் உங்கள் கேம் லாஜிக்கிற்கு FSM-களைப் பயன்படுத்தவும்.

ஆதாரம்: https://dev.to/grzott/i-built-generator-coroutines-for-my-game-engine-then-didnt-use-them-o3g