Wandering Monster: كيفية التخلص من المشاكل على الخريطة

الصورة

بالفعل في عملية إنشاء The Witness أصبحت واحدة من ألعابي المفضلة. لقد بدأت اللعب من اللحظة التي بدأ فيها جوناثان بلو في تطويرها ، ولم أستطع انتظار إصدارها.

على عكس لعبة جون برايد السابقة ، كان مقياس الموارد والبرمجة لدى The Witness أقرب إلى مشاريع AAA من الألعاب المستقلة. يعرف كل من يعمل في مثل هذه المشاريع أن مقدار العمل عند اختيار هذا المسار يزداد بشكل ملحوظ. كان هناك الكثير من الأشخاص الذين يعملون في The Witness أكثر من Braid ، ولكن كما هو الحال مع أي مشروع من هذا المستوى ، هناك العديد من الجوانب التي تتطلب اهتمامًا أكبر مما يمكن لإدارة المشروع تحمله.

لذلك ، أردت دائمًا إيجاد وقت فراغ للمساعدة في إنشاء The Witness عندما يتعلق الأمر بإطلاق اللعبة. لذا في أحد الأيام ، جلسنا أنا وعيد الشكر ، وجون ونظرنا إلى قائمة الأشياء في قاعدة الشفرة التي ستستفيد من الجهود الإضافية من مبرمج آخر. بعد أن قررنا الأهمية النسبية للعناصر في القائمة ، قررنا أن طريقة اللعب ستستفيد أكثر من غيرها إذا أدخلنا تحسينات على رمز حركة اللاعب.

Walkmonster في الجدار


في سياق The Witness ، الهدف من رمز حركة اللاعب هو أن يكون غير مزعج قدر الإمكان. يتعين على اللاعب الانغماس تمامًا في واقع بديل ، وفي هذه اللعبة تجربة كل التفاصيل مهمة. آخر شيء أردناه هو أن يلاحظ اللاعب أنه كان يجلس على الكمبيوتر ويحرك الكاميرا الافتراضية.

لذلك ، يجب أن يكون رمز حركة اللاعب موثوقًا به تمامًا. إذا تمسك اللاعب بالزوايا ، وعلق في الجدران ، وسقط من خلال الأرض ، ونزل من تلة دون القدرة على العودة ، وما إلى ذلك ، فإن هذا سيدمر على الفور وهم الانغماس ويذكر اللاعب بأنه داخل عملية لعبة اصطناعية يتم التدخل فيها بواسطة نظام غير موثوق به النزوح. في بعض الظروف ، يمكن أن يؤدي هذا إلى عواقب وخيمة على اللاعب إذا لم تتح له الفرصة لحل المشكلة عن طريق إعادة تشغيل اللعبة أو إعادة تحميل "حفظ" (ربما قديم جدًا). إذا كنت تلعب في كثير من الأحيان ، فلا بد أنك واجهت مشاكل من هذا النوع ، وأنت تعرف ما أعنيه.

بعد مناقشتنا ، بدأت العمل في هذه المهمة. بادئ ذي بدء ، قررت كتابة أدوات متكاملة للعمل مع رمز حركة اللاعب ، حتى نتمكن من تحليله ومراقبة سلوكه الحالي. بعد فتح المشروع ، واجهت مشكلة خطيرة معروفة لي بالفعل: ما الذي يجب أن أسميه ملف شفرة المصدر الأول؟ هذا هو دائمًا الجزء الأكثر أهمية في أي مشروع ( كما قال بوب بولارد ذات مرة عن أسماء المجموعات الموسيقية والألبومات ). إذا أعطيت الملف المصدر اسمًا مناسبًا ، فسيكون العمل الإضافي واضحًا وسلسًا. اختر الخطأ - يمكنك تدمير المشروع بأكمله.

ولكن ما هو اسم النظام لضمان جودة رمز حركة اللاعب؟ لم يكن عليّ أبدًا كتابة رمز مثل هذا من قبل. عندما فكرت في هذا الأمر ، أدركت أنني شخصياً رأيت مثالاً لمثل هذا الرمز مرة واحدة فقط: عند تشغيل الإصدار التجريبي المبكر من Quake . كانت هناك أخطاء في موقع الوحوش فيها ، وفي نافذة وحدة التحكم يمكنك أن ترى رسائل خطأ تنص على أن الوحوش ، بدلاً من إنشائها على سطح الأرض ، يتم إنشاؤها ، تتقاطع جزئيًا مع هندسة المستويات. بدأت كل رسالة تصحيح بعبارة "Walkmonster in wall at ..."

البنغو! من الصعب العثور على اسم أفضل لملف الشفرة من "walk_monster.cpp". وكنت على يقين من أنه من الآن فصاعدًا سيتم إنشاء التعليمات البرمجية دون مشاكل.

الحركة إلى النقطة


عندما تريد اختبار النظام ، فإن أهم شيء هو اختبار النظام بالفعل . على الرغم من أن هذه القاعدة تبدو بسيطة ، إلا أن الأشخاص الذين يكتبون الاختبارات غالبًا ما يفشلون في الامتثال.

في حالتنا الخاصة ، من السهل جدًا تخيل أننا نختبر رمز حركة اللاعب دون اختباره فعليًا. إليك أحد الأمثلة: يمكنك تحليل حجم التصادمات والأسطح التي يمكنك التحرك عليها في اللعبة ، والبحث عن الأسطح الصغيرة ، والثغرات ، وما إلى ذلك. بعد القضاء على كل هذه المشاكل ، يمكننا القول أن اللاعب الآن قادر على التحرك بأمان والمشي حول العالم.

لكن في الواقع ، قمنا باختبار البيانات وليس الشفرة. من المحتمل جدًا أن يكون هناك أخطاء في رمز الحركة تؤدي إلى سلوك سيء حتى مع البيانات عالية الجودة.

لتجنب مثل هذا الفخ ، أردت أن يكون نظام الاختبار قريبًا قدر الإمكان من سلوك الشخص الذي يتحكم فعليًا في حركة الشخصية في اللعبة. لقد بدأت بكتابة إجراءين من شأنه أن يصبح اللبنات الأساسية لهذا الاختبار.

الإجراء الأول هو الأقرب إلى الإجراءات البشرية الحقيقية. هذا اتصال تحديث يتصل بنظام معالجة الإدخال The Witness ويمرر أحداث لوحة المفاتيح والفأرة المركبة إليه. إنه قادر على القيام بأشياء بسيطة يمكن للشخص القيام بها: انظر حولك ، انتقل نحو نقطة ، انظر إلى نقطة ، وما إلى ذلك. يقوم الإجراء بتنفيذ هذه الإجراءات بمجرد محاكاة تفاعل المستخدم مع لوحة المفاتيح والماوس ، لذلك كنت متأكدًا من أنه عند معالجة إدخال The Witness سيتم كل شيء تمامًا كما كان أثناء الاختبار. في المقالات التالية سأتحدث أكثر عن هذا النظام واستخدامه.

الإجراء الثاني هو خطوة واحدة لا يتم استخدامها على هذا المستوى. هذه وظيفة تسمى DriveTowardPoint ، والتي تتلقى نقطتين في العالم ، وتتسبب في نظام تصادم حالي للاعب ، وتحاول الانتقال بسلاسة من نقطة إلى أخرى. عند تنفيذ العودة ، تنقل معلومات حول المحاولة: ما هي العقبات التي واجهتها في الطريق وما إذا كانت تمكنت من الوصول إلى النقطة الأخيرة.

هذه الوظيفة ليست موثوقة مثل طريقة الاختبار مع الإدخال المركب ، لأنها تقضي على جزء من نظام حركة اللاعب من الاختبار. على سبيل المثال ، أي حالة خاطئة مرتبطة بموقع اللاعب في حالة وجود مشاكل في نظام التصادم لن تؤثر على الاختبار باستخدام هذه الوظيفة. ومع ذلك ، اعتبرت أن هذا المستوى من الاختبار قيم ، لأنه يمكنه اختبار مساحات شاسعة بشكل أسرع بكثير ، لأنه لا يتطلب تنفيذ دورة اللعبة بأكملها ، أي أنه يمكن استخدامه في كثير من الأحيان في جميع أنحاء العالم ، وليس فقط في اختبارات اختبار منفصلة .

وتجدر الإشارة أيضًا إلى أن هذه الوظيفة لا تنقل بيانات الإدخال المادي ؛ على سبيل المثال ، لم يتم تحديد السرعات لنقطة البداية. هذا لأن The Witness ليست لعبة حركة ، لذلك اللاعب لديه القليل من الخصائص المادية الهامة. لا يمكن للاعبين القفز والجري على الجدران وتشغيل وقت الرصاصة. يمكنك دعم مثل هذه السلوكيات باستخدام أنظمة سأصفها لاحقًا ، لكنها تضيف مستويات من التعقيد لم تكن مطلوبة في مشروعنا.

مع ذلك ، بعد تنفيذ DriveTowardPoint ، يمكنني البدء في حل المهمة الأولى للنظام: تحديد مكان انتقال اللاعب إلى جزيرة الشهود .

استكشاف الأشجار العشوائية بسرعة


أين يمكن للاعبين الذهاب؟ يبدو هذا سؤالًا بسيطًا ، ولكنك ستفاجأ بمعرفة عدد الألعاب التي تم إصدارها عندما لم يكن فريق التطوير يعرف الإجابة الحقيقية. إذا كان ذلك ممكنًا ، فأردت أن تكون The Witness واحدة من تلك الألعاب القليلة التي كان المطورون قبل الإصدار يعرفون فيها بالضبط أين يمكن للاعب أن يحصل أو لا يستطيع الحصول على - أي مفاجآت.

هذا يجعل بيان المشكلة (ولكن ليس على الأرجح حلها) بسيطًا جدًا: إذا كانت هناك وظيفة DriveTowardPoint تحدد بشكل موثوق ما إذا كان يمكن للاعب التحرك في خط مستقيم بين نقطتين ، قم بإنشاء خريطة تغطية توضح مكان اللاعب.

لسبب ما ، دون كتابة سطر واحد من التعليمات البرمجية ، لسبب ما اعتقدت أنه سيكون من الأفضل استخدام الاستكشاف السريع للشجرة العشوائية . بالنسبة لأولئك الذين ليسوا على دراية بهذه الخوارزمية ، سأشرح: هذه عملية بسيطة جدًا نسجل فيها جميع النقاط التي قمنا بزيارتها بالإشارة إلى النقطة التي أتينا منها. لإضافة نقطة إلى الشجرة ، نأخذ نقطة هدف عشوائية في أي مكان في العالم ، ونختار النقطة الأقرب إليها ، الموجودة بالفعل في الشجرة ، ونحاول الانتقال من هذه النقطة إلى الهدف. يصبح المكان الذي انتهى بنا فيه إلى نقطة أخذ العينات التالية.

عادة ما يتم استخدام هذه الخوارزمية للبحث عن المسارات: بالتناوب لنقاط عشوائية ، نختار دائمًا نفس النقطة مثل الهدف. هذا يميل إلى استكشاف الفضاء نحو نقطة الهدف ، وهذا هو المطلوب عندما تكون مهمتنا الوحيدة هي تحقيق الهدف. ولكن في هذه الحالة ، أردت إنشاء خريطة كاملة للأماكن التي يمكن أن يقع فيها اللاعب ، لذلك أستخدم عينات عشوائية فقط.

بعد تنفيذ هذه الخوارزمية (لحسن الحظ ، إنها بسيطة للغاية ولا تتطلب الكثير من الوقت) ، رأيت أنه قام بعمل جيد لاستكشاف الفضاء (تظهر المسارات المعروضة بمسارات بيضاء والخطوط الحمراء العمودية تشير إلى الأماكن التي اصطدمت فيها الخوارزمية بعائق) :


ومع ذلك ، بعد ملاحظة سلوكه ، أدركت أنني في الحقيقة لست بحاجة إلى مثل هذه الخوارزمية. على سبيل المثال ، حتى بعد العديد من التكرارات ، بالكاد قادر على استكشاف الغرف المشابهة لتلك الموضحة أدناه ، على الرغم من التغطية الكثيفة للمناطق في الخارج. هذا لأنه ببساطة غير قادر على تحديد نقاط عشوائية كافية داخل الغرف:


إذا فكرت في هذا قبل بدء العمل ، فسأفهم أن ميزة الخوارزميات مثل الاستكشاف السريع للشجرة العشوائية هي أنها تستكشف المساحات عالية الأبعاد بشكل فعال. في الواقع ، هذا عادة ما يكون السبب الرئيسي لاستخدامها. لكن الشاهد ليس لديه مساحات عالية الأبعاد. لدينا مساحة ثنائية الأبعاد (نعم ، موزعة على مجموعة متنوعة معقدة ، ولكن هذا لا يزال مساحة ثنائية الأبعاد).

في هذه المساحة المنخفضة الأبعاد ، تكون مزايا الاستكشاف السريع للشجرة العشوائية ضعيفة ، ولها عيب مهم للغاية بالنسبة لمهمتي: تم تصميم الخوارزمية للبحث الأكثر كفاءة عن المسارات إلى أزواج النقاط المتصلة في الفضاء ، وليس للبحث الفعال عن جميع النقاط التي يمكن الوصول إليها من هذه المساحة. إذا كانت لديك مثل هذه المهمة ، في الواقع ، سيستغرق استكشاف الشجرة العشوائية بسرعة كبيرة قدرًا كبيرًا من الوقت لحلها.

لذلك أدركت بسرعة أنني بحاجة للبحث عن خوارزمية تغطي المساحات المنخفضة الأبعاد بشكل فعال.

تعبئة الفيضانات ثلاثية الأبعاد


عندما فكرت حقًا في اختيار خوارزمية ، أصبح من الواضح أنني في الواقع بحاجة إلى شيء مثل التعبئة القديمة ثنائية الأبعاد الجيدة ، والتي تُستخدم لملء مناطق الصورة النقطية. بالنسبة لأي نقطة بداية ، كان علي فقط ملء المساحة بالكامل ، والتحقق من كل طريقة ممكنة. لسوء الحظ ، ولأسباب عديدة ، سيكون حل The Witness أكثر تعقيدًا بكثير من الصورة النقطية ثنائية الأبعاد.

أولاً ، ليس لدينا مفهوم واضح للترابط المحدود للنقطة. كل الفضاء مستمر. هذا بالنسبة إلى البكسل ، يمكننا بسهولة سرد 4 أماكن محتملة يمكن الوصول إليها من نقطة معينة ، والتحقق من كل منها على حدة.

ثانيًا ، لا يوجد حجم ثابت للموضع في الفضاء ، مثل البكسل في الصورة النقطية. الأسطح التي يتحرك عليها اللاعب ، ويمكن أن تكون العقبات في أي مكان ، ليس لديهم حجم طوبولوجي كحد أقصى أو أدنى ، بالإضافة إلى عدم وجود ارتباط بأي شبكة خارجية.

ثالثًا ، على الرغم من أن الحركة من خلال مساحة The Witness يمكن اعتبارها محليًا على أنها تتحرك على طول الطائرة ، إلا أن المساحة نفسها هي في الواقع مشعب مترابط ومتغير للغاية ، حيث تكون مناطق المشغل للاعب فوق مناطق أخرى مباشرة (في بعض الأحيان يمكن أن يكون هناك عدة مستويات واحدة فوق الأخرى) . بالإضافة إلى ذلك ، هناك اتصالات تختلف باختلاف الظروف العالمية (الأبواب المفتوحة / المغلقة ، والمصاعد التي ترتفع / تنخفض ، وما إلى ذلك).

بالنظر إلى الصعوبات الموصوفة ، من السهل جدًا إصدار نسختك الخاصة من تطبيق التعبئة ، والتي ستملأ نتيجة لذلك بالمناطق المتقاطعة ، وتفقد المسارات المهمة ، والمعلومات الخاطئة حول الاتصالات في الأماكن المعقدة من المشعب. في النهاية ، ستكون الخوارزمية مرهقة للغاية بحيث لا يمكن استخدامها ، لأنه لأخذ التغييرات في حالة العالم في الاعتبار ، يجب إعادة تشغيلها.

لم أفكر في أي حل جيد على الفور ، لذلك قررت أن أبدأ بتجارب بسيطة. باستخدام رمز الاستكشاف السريع للشجرة العشوائية الذي كتبته ، قمت بتغيير تحديد نقاط الهدف من عشوائي إلى شديد التحكم. في كل مرة تتم إضافة نقطة جديدة إلى الشجرة ، أشرت إلى أن النقاط تقع على مسافة وحدة على طول الاتجاهات الرئيسية من النقطة التي سيتم اعتبارها نقطة الهدف المستقبلية ، كما يحدث في تعبئة بسيطة ثنائية الأبعاد.

ولكن بالطبع ، إن لم يكن حذراً ، فإن هذا سيخلق دورة لأخذ عينات غير مجدية. ستتفرع النقطة إلى النقاط الثماني المجاورة حولها ، لكن هذه النقاط الثماني ستحاول مرة أخرى العودة إلى نقطة البداية ، وسيستمر هذا إلى الأبد. لذلك ، بالإضافة إلى التحديد المتحكم فيه لنقاط الهدف ، أحتاج إلى تقييد بسيط: لن يتم أخذ أي نقطة هدف ليست ضمن حد أدنى معين مفيد من نقطة الهدف الحالية في الاعتبار. لدهشتي ، تخلق هاتان القاعدتان البسيطتان تعبئة ناجحة جدًا:


ليس سيئًا لتجربة بسيطة إلى حد ما. لكن الخوارزمية تعاني مما أسميه "صدى الحدود". يمكن رؤية هذا التأثير في لقطة الشاشة التالية المأخوذة أثناء دراسة الخريطة:


في المناطق الخالية من العوائق ، تعمل الخوارزمية جيدًا عن طريق أخذ العينات على مسافات متساوية نسبيًا. ولكن عندما يصادف التقاطع الحدود ، فإنها تخلق نقاطًا "خارج الشبكة" ، أي أنها لا تتم محاذاتها وفقًا لنمط العينات ، التي تملأ الخوارزمية المنطقة المفتوحة المجاورة لها. السبب في أن النقاط "في الشبكة" لا تخلق فسيفساء مكثفة بشكل مفرط لأن كل نقطة جديدة تحاول العودة إلى واحدة من النقاط السابقة تجد النقطة السابقة هناك وترفض إعادة سردها مرة أخرى. ولكن عند إنشاء نقاط جديدة على الحدود ، تكون خارج نطاق المحاذاة تمامًا ، لذلك لا يوجد شيء يمكن أن يمنعهم من العودة إلى المساحة المكتشفة بالفعل. هذا يؤدي إلى إنشاء موجة من العينات المتحيزة ، والتي تستمر حتى تصل إلى خط عشوائي من النقاط في مكان آخر ، وهو قريب بما فيه الكفاية بحيث يمكن للخوارزمية العثور عليها تتزامن مع الجزء الأمامي المتحرك من النقاط.

على الرغم من أن هذا لا يبدو أنه مشكلة خطيرة ، إلا أنه في الواقع أمر بالغ الأهمية. الهدف الأساسي من هذه الخوارزميات هو تركيز العينات في المناطق التي يُرجح أن تؤدي إلى نتائج مثمرة. كلما أمضينا وقتًا أطول في أخذ العينات وإعادة أخذ عينات للمناطق المفتوحة الشاسعة ، قل الوقت الذي سنقضيه في تحديد الوجوه المميزة لهذه المنطقة ، وهي المعلومات التي نحتاجها. نظرًا لأننا نتعامل مع مساحة مستمرة ، ولا يمكن إلا لعدد لا نهائي من العينات وصف شكلها الحقيقي ، فإن نسبة العينات المهمة إلى غير المهمة هي حرفياً مقياس لفعالية الخوارزمية في إنشاء سطح يمكن تمريره للاعب.

ومع ذلك ، هناك حل بسيط لهذه المشكلة بالذات: تحتاج إلى توسيع المسافة التي تعتبر عندها النقطتان "قريبة إلى حد ما". من خلال القيام بذلك ، سنقوم بتقليل كثافة أخذ العينات في الأماكن التي لا تهمنا ، ولكن أيضًا نفقد كثافة أخذ العينات في الأماكن التي تهمنا ، على سبيل المثال ، المناطق المحيطة بالحدود التي نريد التحقق بعناية من وجود "ثقوب".

أخذ عينات اتجاهية محلية


ربما لأنني بدأت مع الشجرة العشوائية السريعة ، حل دماغي محل كل الأفكار الأخرى باستثناء فكرة القرب. استخدمت جميع الخوارزميات السابقة القرب لمهمتها ، على سبيل المثال ، من أجل تحديد نقطة جديدة تحتاج إلى النظر فيها بعد ذلك ، أو لتحديد نقطة تبدأ منها للوصول إلى نقطة هدف جديدة.

ولكن بعد التفكير في المهمة لبعض الوقت ، توصلت إلى إدراك أن كل شيء أصبح أكثر منطقية ، إذا كنا نفكر ليس فقط في القرب ، ولكن أيضًا في الاتجاه . ثم يصبح واضحًا ، ولكن إذا كنت تعمل في مهام مماثلة ، فأنت تعلم أنه من السهل الوقوع في فخ التفكير الضيق وعدم رؤية الصورة الكبيرة ، حتى لو اتضح أنها أبسط. هذا بالضبط ما حدث لي.

عندما قمت بتغيير وجهة نظري للأشياء ، بدا النهج الصحيح لأخذ العينات واضحًا. في كل مرة كنت أرغب في توسيع استكشاف الفضاء الخاص بي من نقطة ، كنت أطلب طلبًا لوجود نقاط قريبة في البيئة المحلية. ومع ذلك ، بدلاً من استخدام المسافة إلى هذه النقاط للبحث ، سأصنفها وفقًا لتوجيهاتها (قبل ذلك استخدمت ثمانية اتجاهات رئيسية فقط ، لكنني أردت أن أجرب نواة أخرى).

في أي اتجاه لا "أرى" فيه النقطة ، أذهب عبر المسافة المحددة وأضيف نقطة في أي مكان توقفت فيه (بغض النظر عما إذا واجهت شيئًا أم لا). إذا رأيت نقطة في أحد الاتجاهات ، فأنا أتحرك هناك وأتأكد من أنني أستطيع الوصول إليها. إذا استطعت ، فأنا أضيف فقط حافة مرئية حتى يتمكن المستخدم بسهولة من رؤية أن النقاط متصلة. إذا لم أستطع ، فأضيف نقطة جديدة عند نقطة التصادم ، مع تحديد حدود العائق.

عملت طريقة أخذ العينات هذه على ما يرام. يسمح لنا بالتحكم بدقة كبيرة في أخذ العينات باستخدام معلمات ملائمة قابلة للتخصيص ، وحفظ جميع النقاط الضرورية وتجنب التغطية بالفسيفساء غير الضرورية ، مما يؤدي إلى ملء المساحة بسرعة كبيرة:


نظرًا لأن الخوارزمية تجري بحثًا على طول الاتجاهات ، ولا تستخدم القرب فقط ، فهي محمية من أصداء الحدود وتحد من أخذ العينات المفرطة فقط لتلك الحدود التي نحتاجها:


علاوة على ذلك ، لا تتأثر الخوارزمية تمامًا بتحولات الحالة أو مشاكل في المجمعات المعقدة. يتعامل فقط مع النقاط ، ويمكن أن تكون هذه النقاط في أي مكان ، ويمكن إضافة نقاط جديدة في أي وقت. إذا كنت قد قمت بالفعل بتجميع خريطة للمنطقة مع إغلاق الباب ، فبعد فتح الباب ، ما عليك سوى وضع نقطة البحث الوحيدة على الجانب الآخر من الباب وطلب الخوارزمية لمواصلة توسيع هذه الخريطة ، وبعد ذلك سيتم توصيلها بشكل صحيح وفحص المنطقة بأكملها خارج الباب بشكل صحيح.

أيضًا ، في أي وقت ، يمكنك تغيير المعلمات الأساسية ، وسيستمر النظام في العمل. هل تريد أن يتم أخذ عينات المنطقة بكثافة أعلى؟ فقط خفض المسافة الافتراضية. يمكن القيام بذلك بالفعل في عملية بناء الخريطة ، وستبدأ الخوارزمية في أخذ العينات بكثافة أعلى دون الحاجة إلى إعادة تعيين النتائج السابقة (والتي قد تستغرق بعض الوقت).

التحقق الأولي من الحواف


تختبر الخوارزمية الافتراضية الحدود بدقة شديدة ، لأن التقاطعات تخلق نقاطًا إضافية ليست جزءًا من نمط أخذ العينات ، لكنها لا تتحقق منها بالضرورة مع العناية اللازمة ، لأنها لا تقوم بأي إجراءات خاصة عند مواجهة العقبات. أدركت أنه نظرًا لأنني كنت أعرف أي نقاط تم إنشاؤها أثناء التصادمات ، فإن نقطتي التصادم المكتشفتين متصلتان بحافة ويمكننا استدعاء عينات إضافية لمحاولة العثور على المزيد من نقاط الحدود في الحي.

لم أقم ببحث نشط في هذا النهج ، لكنني ابتكرت طريقة بدائية لاختبار هذه النظرية ، وبدا لي واعدًا. بعد أن أخذت أي نقطتي تصادم متصلتين بحافة ، أنتقل إلى منتصف الحافة وحاول رسم الطرف العمودي على الحافة. إذا لم تتقاطع الحدود على مسافة قصيرة جدًا ، فأنا أفترض أن الحدود أكثر تعقيدًا ، وأضيف نقطة هدف جديدة لمواصلة البحث في هذه المنطقة.

حتى هذا المخطط البسيط يخلق عينات عالية الجودة وكثيفة جدًا على طول الحدود دون أخذ عينات من المناطق المفتوحة المجاورة بشكل غير ضروري. إليك منطقة بها عدة حدود ، ولكن بدون فحص الحواف:


وهنا نفس المنطقة مع فحص الحواف:


بغض النظر عن مدى سروري بهذه النتيجة ، فوجئت بعدم وجود خوارزميات أفضل بشكل كبير لأخذ عينات الحدود ، وسأحاول التقاط بعض الطرق الإضافية في المستقبل.

انتصارات سريعة


حتى بعد أن استثمرت القليل من الوقت فقط في التطوير وإنشاء رمز بسيط إلى حد ما ، تأكدت من أن Walk Monster يخلق بالفعل مخرجات مناسبة تمامًا يمكنها اكتشاف مشاكل حقيقية في اللعبة. فيما يلي أمثلة على المشكلات التي اكتشفتها أثناء تطوير الخوارزمية:


لا ينبغي أن تكون المنحدرات على جوانب هذه المنصة قابلة للمرور ، ولكن يمكن للاعب المشي عليها. حدث هذا لأنه في رمز حركة اللاعب هناك طريقة سيئة مرضية لمعالجة الهندسة المائلة. الآن أعلم أنه موجود ، وسأصححه عندما يتعلق الأمر بضمان موثوقيته.


كان من المفترض أن تكون الشاهد لعبة تأملية ، ولكن يتساءل لماذا يبدو أن هناك حجرًا ، على الرغم من أنه ليس كذلك ، لم يكن واحدًا من أكوانه. كما قد تخمن ، نشأت هذه المشكلة لأن شخصًا ترك مقدار التصادم في اللعبة بعد إزالة الشكل الهندسي للدلالة عليه. يمكن أن يحدث هذا بسهولة ، ومن الجيد جدًا أن لدينا أداة يمكنها التعرف بسرعة على مثل هذه الأخطاء بحيث لا يضطر الناس إلى ذلك.



كان من المفترض أن تكون هذه الأشياء صخور غير سالكة ، لكن ووك مونستر وجد أن هذا لم يحدث. الأسوأ من ذلك ، أن Walk Monster وجد أنه لسبب ما ، فإن المسار يكون باتجاه واحد فقط (من لقطة الشاشة من اليسار إلى اليمين) ، ولكن هذا لا ينبغي أن يكون. لقد تأكدت من أن اللاعب يمكنه فعل ذلك (نجحت). من المثير للاهتمام ملاحظة حدوث مثل هذه الأخطاء!

أسئلة مفتوحة


عندما ترى نتائج جيدة يمكن تطويرها بشكل أكبر ، تكون ملهمة. كما قلت ، إذا اخترت اسمًا مناسبًا لملفات المصدر ، فسيكون كل شيء يسير كالساعة! ولكن تم الانتهاء من كل هذا العمل في غضون أيام قليلة فقط ، لذلك فهو بعيد عن أن يكون شاملاً ، وقد تم عمل الكثير بشكل مرتجل تمامًا. إذا كان لدي الوقت الكافي لمزيد من التطوير لهذه الأنظمة ، فمن الجدير الإجابة على عدة أسئلة.

أولاً ، ما هي المعالجة اللاحقة التي يجب إجراؤها باستخدام البيانات بحيث يكون من السهل تصورها؟ سيكون من الصعب على الأشخاص اكتشاف شبكة من النقاط والحواف غير المجهزة ، ولكن إذا قمت بتحسين وصف البيانات ، فمن المحتمل أن يجعل ذلك من الصعب تقييم المناطق الصعبة القابلة للمرور من النظرة الأولى.

ثانيًا ، كيف يمكن تحسين أنماط أخذ العينات حول الحدود لضمان العثور على أقصى عدد من "الثقوب"؟ هل هناك طرق جيدة لوصف تقليص الأشكال في شبكة ، وهل هناك أي مخططات للتغطية بالفسيفساء عالية الجودة تزيد من احتمالية عبور هذه الأرقام والمرور بها؟

ثالثًا ، ما هي أنماط أخذ العينات الأفضل لملء الفراغات - العادية أو العشوائية؟ يمكنني بسهولة تغيير معايير اختيار النقاط المستهدفة لإنشاء المزيد من الأنماط العشوائية ، ولكن ليس من الواضح جدًا ما إذا كان هذا يستحق القيام به ، وإذا كان الأمر كذلك ، ما أنواع الأنماط العشوائية التي ستكون أفضل.

رابعاً ، ما هي المعلومات الأخرى التي نريد الحصول عليها من خرائط المناطق القابلة للتمرير إذا تعلمنا بالفعل كيفية بنائها؟ على سبيل المثال ، من السهل جدًا توسيع نظام موجود بوظائف مثل البحث عن المسارات أو خرائط المسافة ، بحيث يمكن للمستخدم تحديد نقطة وطلب أقصر مسار بينها وبين نقطة أخرى ، أو رؤية خريطة حرارية للمسافة بين نقطة ونقاط أخرى من الخريطة. هل ستكون مثل هذه الاستفسارات مفيدة؟ ما الاستفسارات الأخرى التي يمكنني استخدامها؟

في الوقت الحالي ، تعتبر تصورات Walk Monster للمناطق القابلة للتمرير أكثر من كافية لإظهار أن رمز حركة اللاعب سيئ جدًا. لقد خططت للانتقال إلى إنشاء نظام لبطاقات الاختبار الليلية باستخدام طريقة محاكاة إدخال المستخدم ، ولكن من الواضح أن لدينا بالفعل مشاكل كافية لحلها بدون هذه الخطوة. لذلك ، ستكون الخطوة التالية هي زيادة موثوقية رمز حركة اللاعب. وبينما أعمل على هذا ، أود أن أتحقق مما إذا كان من الممكن زيادة سرعة التنفيذ بمقدار أمر واحد أو أمرين ، لأنه في حين أن عمل Walk Monster بطيء جدًا بسبب نظام الفرامل من الاصطدامات.

Source: https://habr.com/ru/post/ar423519/


All Articles