ريم تصنع لعبة ألغاز في الشارقة، وكتبت أول حركة لها هكذا: مع كل إطار، حرك اللاعب ثلاث نقاط إلى اليمين.
player.x += 3
على هاتفها اللعبة سليمة. على هاتف أخيها الأحدث اللاعب يمشي ضعف السرعة ويتجاوز كل حافة. الكود واحد، والفرق كله أن الهاتف الأحدث يرسم إطارات أكثر في الثانية.
الحلقة ثلاث خطوات، وتجري وقع شيء أو لم يقع
الحلقة تقرأ المدخلات، ثم تقدم العالم، ثم ترسم، وتجري وقع شيء أو لم يقع. هذا هو الفرق الأول بين اللعبة وبين أي برنامج آخر في هذا الركن من الأطلس. البرنامج العادي ينتظر حدثا ثم يستيقظ. اللعبة لا تنتظر شيئا: هي تدور ستين مرة في الثانية على شاشة ساكنة وعلى شاشة فيها انفجار، وتصرف الميزانية نفسها.
وقراءة المدخلات في هذه الحلقة ليست انتظار ضغطة. هي سؤال عن حالة اللحظة: أي زر مضغوط الآن، لا أي زر ضغط منذ آخر مرة. من كتبها على شكل حدث حصل على شخصية تتوقف لحظة بين أول ضغطة وتكرارها، لأنه ورث تأخير لوحة المفاتيح من نظام لم يكن يفكر في لعبة.
16.7 مللي ثانية لكل شيء، لا لكل شيء على حدة
ميزانية الإطار عند 60 إطارا في الثانية هي 16.7 مللي ثانية لكل شيء. الرقم قسمة واحدة: ثانية على ستين. وفيه تدخل قراءة المدخلات وحساب الحركة وحل التصادمات وتقرير ما يظهر على الشاشة والرسم، كلها معا لا كل واحدة منها.
وحين يطول شيء واحد تتأخر البقية، ولا يظهر ذلك في صورة رسالة خطأ. يظهر في صورة تقطيع يشعر به اللاعب ولا يستطيع تسميته. ولهذا يكون أثمن سطر في مشروع لعبة هو الذي يطبع زمن الإطار على الشاشة أثناء التطوير، لا في نهايته.
وهذه الميزانية هي ما يجعل أساسيات البرمجة تصل مبكرة هنا أكثر من أي مكان آخر: الحلقة داخل الحلقة التي لا يلاحظها برنامج يعمل مرة في الدقيقة تقتل لعبة ستين مرة في الثانية.
اضرب في الزمن المنقضي، لا في الإطار
عطل ريم كله في السطر الأول من هذه الصفحة. الجهاز هو الذي يقرر كم إطارا يرسم في الثانية، فالحركة المكتوبة لكل إطار تصير حركة لكل قدرة جهاز.
الزمن المنقضي: اضرب كل حركة في الثواني التي مضت منذ الإطار السابق. والسطر يصير:
player.x += 180 * delta
و180 هنا ليست ثلاثا. هي سرعة بوحدة معلنة: 180 نقطة في الثانية. على جهاز يرسم 60 إطارا يكون النصيب 3 نقاط للإطار، وعلى جهاز يرسم 120 يكون 1.5، والمسافة في الثانية واحدة على الاثنين. والفائدة الثانية أن الرقم صار قابلا للقراءة: 180 نقطة في الثانية جملة يفهمها من يوازن اللعبة، و3 لكل إطار ليست جملة أصلا.
ويبقى موضع واحد لا يصلحه هذا. خطوة ثابتة للفيزياء وخطوة متغيرة للرسم، لأن جسما سريعا يضرب في زمن كبير ينتقل من أمام الجدار إلى خلفه بين إطارين، فلا يقع تصادم قط. فتحسب الفيزياء بخطوات ثابتة صغيرة مهما كان زمن الإطار، ويرسم ما بينها بالاستيفاء. والمحركات الثلاثة كلها تعطي دالتين منفصلتين لهذا، وهذا هو سبب وجودهما لا اختلاف في التسمية.
أربع قطع، والناقصة منها تحول اللعبة إلى عرض
القطع الأربع ليست مراحل ولا أقساما. الأنظمة هي القواعد والحلقة والكود الذي يملك 16.7 مللي ثانية لتشغيلها. وسبب الاستمرار هو ما يقرره اللاعب ولماذا تستحق الدقيقة التالية. والأصول تبنى على ميزانية يقررها المحرك قبل الذوق. والعشرة بالمئة الأخيرة قوائم وحفظ وخيارات ونسخة المتجر.
والرابعة هي التي تنقص من كل مشروع متروك تقريبا، وهي التي تأخذ من الوقت قدر الثلاث الأخرى مجتمعة. ومن أراد أن يقرأ عن الثانية منها فموضعها تصميم الألعاب، وعن الثالثة فن الألعاب.
لعبة واحدة
أربع قطع، واللعبة الناقصة واحدة منها عرض لا لعبة
ليست مراحل وليست أقساما. حذف واحدة منها لا يصغر اللعبة، يجعلها غير منتهية.
- 01الأنظمةالقواعد والحلقة والكود الذي يملك 16.7 مللي ثانية ليشغلها
- 02سبب الاستمرارما الذي يقرره اللاعب، ولماذا تستحق الدقيقة التالية
- 03الأصول على ميزانيةعدد مثلثات يقرره المحرك قبل الذوق، ونص عربي يقرر شكل الواجهة
- 04العشرة بالمئة الأخيرةقوائم وحفظ وخيارات ونسخة المتجر، وهي نصف الرزنامة
القطع غير متساوية في الساعات. الرابعة تأخذ عادة قدر الثلاث الأخرى مجتمعة، وهي الناقصة من كل مشروع متروك تقريبا.
الجدار هنا كلمة عربية لا تتصل حروفها
أول شاشة تكتبها ريم بالعربية تخرج على هذا الشكل: حروف منفصلة، مقلوبة الترتيب، مقروءة من اليسار. اللعبة سليمة والنص عطب.
وسببه أن النص العربي يحتاج طبقتين لا يحتاجهما النص اللاتيني: تشكيل الحروف حسب موضعها في الكلمة، وترتيب ثنائي الاتجاه للسطر. المتصفح ونظام الهاتف يفعلان هذا وحدهما، ومحركات الألعاب ترسم النص بنفسها على النسيج، فمنها ما يحمل هذه الطبقة ومنها ما لا يحملها، ومنها ما يحملها في مكون ولا يحملها في آخر.
ولا تصدق في هذا خبرا، بما فيه هذا السطر. الفحص عشر دقائق ويجرى قبل اختيار المحرك لا بعد ستة أشهر: أنشئ مشروعا فارغا، وضع في عنصر نص كلمة «مرحبا»، وشغل. إن خرجت الحروف متصلة ومرتبة من اليمين فالمحرك يحمل الطبقتين. وإن خرجت منفصلة فأنت أمام ثلاثة خيارات لا أكثر: خط ومكون نص يدعمان التشكيل، أو حزمة خارجية تعالج النص قبل عرضه، أو رسم النصوص صورا.
وهذا معيار اختيار محرك لا يذكر في أي مقارنة إنجليزية بين المحركات، ووزنه لقارئ هذه الصفحة أثقل من فرق الأداء الذي تدور حوله تلك المقارنات. ومن اكتشفه بعد بناء أربعين شاشة يدفعه مرتين: مرة في العلاج، ومرة في كل شاشة بنيت على المكون الخاطئ.
ويلحق به قراران أصغر يقرران معا هل تبدو اللعبة عربية أم مترجمة: الأرقام داخل الواجهة تبقى لاتينية إن كان باقي المشروع كذلك ولا تخلط، والواجهة تنعكس بأكملها مع النص، أما شريط التقدم وعقارب الوقت فلا ينعكسان لأنهما يمثلان زمنا ومقدارا.
ثلاثة محركات، والفرق بينها ليس ما يقال عنه
Godot هو المدخل الافتراضي اليوم لمشروع فردي، وحل محل كتابة محرك من الصفر، وهو ما كان يعنيه مشروع لعبة قبل 2015 تقريبا. مجاني ومفتوح المصدر بلا رسوم ولا حصة من الإيرادات ولا حساب، وحجمه صغير ينزل على اتصال متواضع، وهذه أشياء تعني قارئا في المنطقة أكثر مما تعني غيره.
وUnity أوسعها انتشارا في إعلانات الوظائف وأكبرها سوق أصول جاهزة، وحل محل الشيء نفسه قبل ذلك بسنوات. ولمحرك Unity نسخة مجانية للأفراد تحت حد من الإيراد، وما فوقه اشتراك بالدولار يحاسب شهريا. وUnreal للعمل الثلاثي الأبعاد عالي الإنتاج، ومجاني حتى حد من الإيراد ثم بحصة منه. والحد والحصة كلاهما يتغير، فيقرأ من صفحة الترخيص نفسها قبل بدء مشروع تجاري لا من درس.
والفحص العربي في القسم السابق يجرى على أي من الثلاثة قبل اختياره، ونتيجته أثقل في الميزان من كل ما سبق في هذه الفقرة.
الخمسة تحت هذه الصفحة، والسؤال الذي يليها
المحركات أول ما يفتح، لا لأنها الأهم بل لأن الاختيار يقيد ما بعده، والفحص أعلاه جزء منه. ثم برمجة الألعاب وفيها الحلقة والزمن المنقضي والخطوة الثابتة مكتوبة كودا لا وصفا. وإطلاق اللعبة هي القطعة الرابعة، وتقرأ مبكرا لا في آخر المشروع، لأن قراءتها متأخرة هي تحديدا سبب بقائها ناقصة.
ومن يبني للهاتف قبل الحاسوب، وهو حال أكثر من يقرأ هذه الصفحة، يجد قيود الجهاز والمتجر والمراجعة تحت برمجة التطبيقات، وهي قيود تسبق كل ما في هذه الصفحة زمنيا.
ويبقى سؤال يصل بعد أول لعبة تعمل. لعبة ريم تحفظ تقدم اللاعب في ملف على الجهاز، فإذا حذف التطبيق ضاع كل شيء، وإذا أرادت لوحة أفضل اللاعبين احتاجت مكانا يراه الجميع. أين يسكن تقدم اللاعبين حين يكونون ألفا لا واحدا؟ جوابه في قواعد البيانات.