ನಾನು ನನ್ನ ಗೇಮ್ ಇಂಜಿನ್ಗಾಗಿ ಕೊರೂಟಿನ್ಗಳನ್ನು (Coroutines) ನಿರ್ಮಿಸಿದೆ, ನಂತರ ಅವುಗಳನ್ನು ಬಳಸಲಿಲ್ಲ
ನಾನು ನನ್ನ ಗೇಮ್ ಇಂಜಿನ್ಗಾಗಿ ಒಂದು ಜನರೇಟರ್ ಕೊರೂಟಿನ್ (generator coroutine) ವ್ಯವಸ್ಥೆಯನ್ನು ನಿರ್ಮಿಸಿದೆ. ಅದರಲ್ಲಿ 122 ಸಾಲುಗಳ ಕೋಡ್ ಮತ್ತು 12 ಪರೀಕ್ಷೆಗಳಿದ್ದವು. ಇದು 'callback hell' ಸಮಸ್ಯೆಯನ್ನು ಪರಿಹರಿಸಿತು. ಇದು ಸ್ಕ್ರಿಪ್ಟ್ಗಳು ನೇರ ರೇಖೆಯಂತೆ ಕಾಣುವಂತೆ ಮಾಡಿತು.
ನಂತರ ನಾನು ಅದನ್ನು ನನ್ನ ಗೇಮ್ ಲಾಜಿಕ್ (game logic) ಗಾಗಿ ಬಳಸದಿರಲು ನಿರ್ಧರಿಸಿದೆ. ಬದಲಾಗಿ ನಾನು ಫೈनाइट ಸ್ಟೇಟ್ ಮೆಷಿನ್ (Finite State Machine - FSM) ಅನ್ನು ಬಳಸಿದೆ.
ಅದಕ್ಕೆ ಕಾರಣ ಇಲ್ಲಿದೆ.
ಹೆಚ್ಚಿನ ಟ್ಯುಟೋರಿಯಲ್ಗಳು ರಿಯಲ್-ಟೈಮ್ ಗೇಮ್ಗಳಲ್ಲಿ ಜನರೇಟರ್ಗಳೊಂದಿಗೆ ಇರುವ ಎರಡು ದೊಡ್ಡ ಸಮಸ್ಯೆಗಳನ್ನು ನಿರ್ಲಕ್ಷಿಸುತ್ತವೆ: ಮೆಮೊರಿ (memory) ಮತ್ತು ಸೇವಿಂಗ್ (saving).
- ಮೆಮೊರಿ ಒತ್ತಡ (Memory Pressure)
ನೀವು ಪ್ರತಿ ಬಾರಿ ಜನರೇಟರ್ನಲ್ಲಿ
.next()ಅನ್ನು ಕರೆ ಮಾಡಿದಾಗ, ಜಾವಾಸ್ಕ್ರಿಪ್ಟ್ ಇಂಜಿನ್ ಒಂದು ಹೊಸ ಆಬ್ಜೆಕ್ಟ್ ಅನ್ನು ರಚಿಸುತ್ತದೆ. ಈ ಆಬ್ಜೆಕ್ಟ್ ಪ್ರಸ್ತುತ ಮೌಲ್ಯ ಮತ್ತು ಸ್ಥಿತಿಯನ್ನು (status) ಒಳಗೊಂಡಿರುತ್ತದೆ.
60 FPS ನಲ್ಲಿ ಚಲಿಸುವ ಗೇಮ್ ಲೂಪ್ನಲ್ಲಿ, ಇದು ನಿರಂತರ 'garbage collection' ಒತ್ತಡವನ್ನು ಉಂಟುಮಾಡುತ್ತದೆ. ಕಾರ್ಯಕ್ಷಮತೆಯನ್ನು ಸ್ಥಿರವಾಗಿಡಲು ನನ್ನ ಇಂಜಿನ್ 'zero-allocation' ನಿಯಮವನ್ನು ಅನುಸರಿಸುತ್ತದೆ. ಜನರೇಟರ್ಗಳು ಆ ನಿಯಮವನ್ನು ಮುರಿಯುತ್ತವೆ. ಅವು ಪ್ರತಿ ಫ್ರೇಮ್ನಲ್ಲಿ ಸಣ್ಣ ಆಬ್ಜೆಕ್ಟ್ಗಳ ಹರಿವನ್ನು (stream) ಸೃಷ್ಟಿಸುತ್ತವೆ.
- ಸೀರಿಯಲೈಸೇಶನ್ ಸಮಸ್ಯೆ (The Serialization Problem) ಒಂದು ಗೇಮ್ ಅನ್ನು ಸೇವ್ (save) ಮತ್ತು ಲೋಡ್ (load) ಮಾಡುವ ಅಗತ್ಯವಿರುತ್ತದೆ. ನೀವು ಪ್ರಸ್ತುತ ಗೇಮ್ ಸ್ಥಿತಿಯನ್ನು (game state) ಡೇಟಾ ಆಗಿ ಮತ್ತು ಮತ್ತೆ ಮೊದಲಿನ ಸ್ಥಿತಿಗೆ ಪರಿವರ್ತಿಸಬೇಕಾಗುತ್ತದೆ.
ನೀವು ನಿಂತಿರುವ (paused) ಜನರೇಟರ್ ಅನ್ನು ಸೀರಿಯಲೈಸ್ (serialize) ಮಾಡಲು ಸಾಧ್ಯವಿಲ್ಲ. ಅದರ ಸ್ಥಿತಿಯು ನೀವು ಪ್ರವೇಶಿಸಲು ಸಾಧ್ಯವಾಗದ ಇಂಟರ್ನಲ್ ಇಂಜಿನ್ ಸ್ಲಾಟ್ಗಳಲ್ಲಿ ಇರುತ್ತದೆ. ನೀವು ಅದನ್ನು ಸೇವ್ ಮಾಡಲು ಪ್ರಯತ್ನಿಸಿದರೆ, ನಿಮಗೆ ಖಾಲಿ ಆಬ್ಜೆಕ್ಟ್ ಅಥವಾ ಎರರ್ (error) ಸಿಗುತ್ತದೆ.
ಫೈनाइट ಸ್ಟೇಟ್ ಮೆಷಿನ್ (FSM) ವಿಭಿನ್ನವಾಗಿದೆ. ಇಲ್ಲಿ ಸ್ಥಿತಿಯು ಕೇವಲ ಒಂದು ಕಾಂಪೊನೆಂಟ್ನಲ್ಲಿರುವ ಸ್ಟ್ರಿಂಗ್ (string) ಆಗಿರುತ್ತದೆ.
- ಸೇವ್ ಮಾಡಲು: ಸ್ಟ್ರಿಂಗ್ ಅನ್ನು ಡಿಸ್ಕ್ಗೆ ಬರೆಯಿರಿ.
- ಲೋಡ್ ಮಾಡಲು: ಸ್ಟ್ರಿಂಗ್ ಅನ್ನು ಓದಿ ಮತ್ತು FSM ಅನ್ನು ಅಲ್ಲಿಂದ ಪ್ರಾರಂಭಿಸಲು ತಿಳಿಸಿ.
ವೃತ್ತಿಪರ ಗೇಮ್ಗೆ ಮುಖ್ಯವಾದ ಎರಡು ವಿಷಯಗಳನ್ನು FSM ನಿರ್ವಹಿಸುವುದರಿಂದ ಅದು ಗೆದ್ದಿತು: ಕಾರ್ಯಕ್ಷಮತೆ (performance) ಮತ್ತು ಪರ್ಸಿಸ್ಟೆನ್ಸ್ (persistence).
ಹೇಗೆ ಆಯ್ಕೆ ಮಾಡುವುದು:
ಲಾಜಿಕ್ ಮುಖ್ಯ ಫ್ರೇಮ್ ಲೂಪ್ನ ಒಳಗಿದೆಯೇ?
- ಇಲ್ಲ: ಜನರೇಟರ್ ಕೊರೂಟಿನ್ ಬಳಸಿ. ಅಸೆಟ್ ಲೋಡ್ ಮಾಡುವುದು ಅಥವಾ ಆನ್ಬೋರ್ಡಿಂಗ್ನಂತಹ ಏಕಕಾಲಿಕ ಪ್ರಕ್ರಿಯೆಗಳಿಗೆ ಅವು ಉತ್ತಮವಾಗಿವೆ.
- ಹೌದು: ಮುಂದಿನ ಪ್ರಶ್ನೆಯನ್ನು ಕೇಳಿ.
ಸ್ಥಿತಿಯು ಸೇವ್ ಮಾಡಿದ ನಂತರವೂ ಉಳಿಯಬೇಕೇ?
- ಹೌದು: ಫೈनाइट ಸ್ಟೇಟ್ ಮೆಷಿನ್ ಬಳಸಿ.
- ಇಲ್ಲ: ಮುಂದಿನ ಪ್ರಶ್ನೆಯನ್ನು ಕೇಳಿ.
ನೀವು ಏಕಕಾಲದಲ್ಲಿ ಅನೇಕ ಸೀಕ್ವೆನ್ಸ್ಗಳನ್ನು (sequences) ರನ್ ಮಾಡುತ್ತಿದ್ದೀರಾ?
- ಹೌದು: ಫೈनाइट ಸ್ಟೇಟ್ ಮೆಷಿನ್ ಬಳಸಿ.
- ಇಲ್ಲ: ಜನರೇಟರ್ ಕೊರೂಟಿನ್ ಬಳಸಿ.
ಜನರೇಟರ್ಗಳು ತಪ್ಪು ನಿರ್ಧಾರವಲ್ಲ. ಅವು ಕೇವಲ 'hot path' ಗೆ ಸರಿಯಾದ ಸಾಧನಗಳಲ್ಲ. ಅವುಗಳನ್ನು 'async glue' ಗಾಗಿ ಬಳಸಿ, ಆದರೆ ನಿಮ್ಮ ಗೇಮ್ ಲಾಜಿಕ್ ಗಾಗಿ FSM ಗಳನ್ನು ಬಳಸಿ.
ಮೂಲ: https://dev.to/grzott/i-built-generator-coroutines-for-my-game-engine-then-didnt-use-them-o3g
