چگونه Slow Roads گیمرها و توسعه دهندگان را به یک اندازه مجذوب می کند و قابلیت های شگفت انگیز سه بعدی را در مرورگر برجسته می کند.

پتانسیل WebGL را با مناظر بی‌نهایت و رویه‌ای این بازی رانندگی معمولی کشف کنید.

Slow Roads یک بازی رانندگی معمولی با تاکید بر مناظر بی‌پایان رویه‌ای است که همه در مرورگر به عنوان یک برنامه WebGL میزبانی می‌شوند. برای بسیاری، چنین تجربه فشرده ای ممکن است در زمینه محدود مرورگر نامناسب به نظر برسد - و در واقع، اصلاح این نگرش یکی از اهداف من از این پروژه بوده است. در این مقاله، برخی از تکنیک‌هایی را که برای پیمایش موانع عملکرد در ماموریتم برای برجسته کردن پتانسیل سه بعدی در وب که اغلب نادیده گرفته می‌شود، بیان می‌کنم.

توسعه سه بعدی در مرورگر

پس از انتشار Slow Roads، یک نظر تکراری را در بازخورد دیدم: "من نمی دانستم این امکان در مرورگر وجود دارد". اگر شما این احساس را به اشتراک بگذارید، مطمئناً در اقلیت نیستید. طبق نظرسنجی 2022 State of JS ، حدود 80٪ از توسعه دهندگان هنوز WebGL را آزمایش نکرده اند. برای من، مایه شرمساری است که این همه پتانسیل ممکن است از دست برود، به خصوص وقتی صحبت از بازی های مبتنی بر مرورگر می شود. با Slow Roads امیدوارم بتوانم WebGL را بیشتر در کانون توجه قرار دهم و شاید تعداد توسعه دهندگانی که از عبارت "موتور بازی جاوا اسکریپت با کارایی بالا" مخالفت می کنند را کاهش دهم.

WebGL ممکن است برای بسیاری مرموز و پیچیده به نظر برسد، اما در سال های اخیر اکوسیستم های توسعه آن تا حد زیادی به ابزارها و کتابخانه های بسیار توانمند و راحت تبدیل شده اند. اکنون آسان‌تر از همیشه برای توسعه‌دهندگان فرانت‌اند است که 3D UX را در کار خود بگنجانند، حتی بدون تجربه قبلی در گرافیک کامپیوتری. Three.js ، کتابخانه پیشرو WebGL، به عنوان پایه ای برای بسیاری از توسعه ها، از جمله react-three-fiber که اجزای سه بعدی را به چارچوب React می آورد، عمل می کند. در حال حاضر ویرایشگرهای جامع بازی مبتنی بر وب مانند Babylon.js یا PlayCanvas نیز وجود دارد که یک رابط آشنا و زنجیره‌های ابزار یکپارچه ارائه می‌دهند.

با وجود کاربرد قابل توجه این کتابخانه ها، پروژه های جاه طلبانه در نهایت با محدودیت های فنی محدود می شوند. شک و تردید نسبت به ایده بازی مبتنی بر مرورگر ممکن است تاکید کند که جاوا اسکریپت تک رشته ای و محدود به منابع است. اما پیمایش این محدودیت‌ها ارزش پنهان را باز می‌کند: هیچ پلتفرم دیگری همان دسترسی فوری و سازگاری انبوه را که توسط مرورگر فعال شده است ارائه نمی‌کند. کاربران در هر سیستم دارای مرورگر می‌توانند بدون نیاز به نصب برنامه‌ها و بدون نیاز به ورود به سرویس‌ها، با یک کلیک شروع به بازی کنند. ناگفته نماند که توسعه دهندگان از راحتی زیبای داشتن فریم ورک های جلویی قوی برای ایجاد رابط کاربری یا مدیریت شبکه برای حالت های چند نفره لذت می برند. این مقادیر، به نظر من، همان چیزی است که مرورگر را به یک پلتفرم عالی برای بازیکنان و توسعه‌دهندگان تبدیل می‌کند – و همانطور که توسط Slow Roads نشان داده شده است، محدودیت‌های فنی ممکن است اغلب به یک مشکل طراحی تقلیل یابد.

دستیابی به عملکرد صاف در جاده های آهسته

از آنجایی که عناصر اصلی Slow Roads شامل حرکت با سرعت بالا و تولید مناظر پرهزینه است، نیاز به عملکرد روان بر هر تصمیم طراحی من تأکید داشت. استراتژی اصلی من شروع با یک طراحی گیم پلی کاهش یافته بود که اجازه می داد میانبرهای متنی در معماری موتور گرفته شود. از جنبه منفی، این بدان معناست که برخی از ویژگی‌های خوب را برای دستیابی به مینیمالیسم معاوضه کنید، اما منجر به یک سیستم سفارشی و فوق بهینه شده می‌شود که به خوبی در مرورگرها و دستگاه‌های مختلف اجرا می‌شود.

در اینجا به تفکیک اجزای کلیدی که Slow Roads را لاغر نگه می‌دارند، ارائه می‌شود.

شکل دادن به موتور محیط پیرامون گیم پلی

به عنوان جزء کلیدی بازی، موتور تولید محیط به طور اجتناب‌ناپذیری گران است و به‌طور موجهی بیشترین بودجه را برای حافظه و محاسبات می‌گیرد. ترفند مورد استفاده در اینجا در برنامه ریزی و توزیع محاسبات سنگین در یک دوره زمانی است، به طوری که نرخ فریم با افزایش عملکرد قطع نشود.

محیط از کاشی‌های هندسی تشکیل شده است که از نظر اندازه و وضوح (که به عنوان «سطوح جزئیات» یا LoDs طبقه‌بندی می‌شوند) بسته به اینکه چقدر به دوربین نزدیک می‌شوند، متفاوت هستند. در بازی‌های معمولی با دوربین رومینگ آزاد، LoD‌های مختلف باید دائماً بارگیری و تخلیه شوند تا محیط اطراف بازیکن را به هر کجا که می‌خواهند بروند، با جزئیات مشخص کنند. این می تواند یک عملیات پرهزینه و بیهوده باشد، به خصوص زمانی که خود محیط به صورت پویا تولید می شود. خوشبختانه، این قرارداد را می‌توان در جاده‌های آهسته به‌خاطر انتظار زمینه‌ای که کاربر باید در جاده بماند، کاملاً براندازی کرد. در عوض، هندسه با جزئیات بالا را می توان برای راهروی باریکی که مستقیماً در کنار مسیر قرار دارد، رزرو کرد.

نموداری که نشان می‌دهد چگونه تولید جاده از قبل می‌تواند امکان برنامه‌ریزی فعال و ذخیره‌سازی محیط را فراهم کند.
نمایی از هندسه محیط در جاده‌های آهسته که به‌عنوان یک قاب سیمی ارائه شده است، که نشان‌دهنده دالان‌هایی با هندسه با وضوح بالا در کنار جاده است. بخش‌های دور از محیط، که هرگز نباید از نزدیک دیده شوند، با وضوح بسیار پایین‌تری رندر می‌شوند.

خط وسط جاده به خودی خود خیلی زودتر از ورود بازیکن ایجاد می‌شود و امکان پیش‌بینی دقیق زمان و مکان مورد نیاز جزئیات محیط را فراهم می‌کند. نتیجه یک سیستم ناب است که می تواند به طور فعال برنامه ریزی کارهای پرهزینه را انجام دهد و فقط حداقل های مورد نیاز را در هر نقطه از زمان ایجاد کند و هیچ تلاشی برای جزئیاتی که دیده نمی شوند هدر نمی دهد. این تکنیک تنها به این دلیل امکان‌پذیر است که جاده یک مسیر واحد و بدون انشعاب است - نمونه‌ای خوب از ایجاد معاوضه‌های گیم‌پلی که میانبرهای معماری را در خود جای می‌دهند.

نموداری که نشان می‌دهد چگونه تولید جاده از قبل می‌تواند امکان برنامه‌ریزی فعال و ذخیره‌سازی محیط را فراهم کند.
با نگاه کردن به فاصله معینی در امتداد جاده، تکه‌های محیطی را می‌توان پیش‌پرداخت و به تدریج درست قبل از نیاز ایجاد کرد. علاوه بر این، هر تکه‌ای که در آینده نزدیک دوباره مورد بازبینی قرار می‌گیرد، می‌تواند شناسایی و ذخیره شود تا از بازسازی غیرضروری جلوگیری شود.

حساس بودن با قوانین فیزیک

دومین مورد نیاز محاسباتی موتور محیط، شبیه سازی فیزیک است. Slow Roads از موتور فیزیک سفارشی و حداقلی استفاده می کند که هر میانبر موجود را انجام می دهد.

صرفه جویی عمده در اینجا این است که در وهله اول از شبیه سازی اشیاء بیش از حد پرهیز کنید - با کم کردن مواردی مانند برخوردهای پویا و اشیاء تخریب پذیر، به بافت ذن مینیمال متمایل شوید. این فرض که وسیله نقلیه در جاده می ماند به این معنی است که برخورد با اجسام خارج از جاده را می توان نادیده گرفت. علاوه بر این، رمزگذاری جاده به عنوان یک خط وسط پراکنده، ترفندهای ظریفی را برای تشخیص سریع برخورد با سطح جاده و ریل‌های محافظ، که همه بر اساس بررسی فاصله تا مرکز جاده است، امکان پذیر می‌سازد. پس از آن رانندگی خارج از جاده گران تر می شود، اما این نمونه دیگری از مبادله منصفانه است که متناسب با زمینه گیم پلی است.

مدیریت ردپای حافظه

به عنوان یکی دیگر از منابع محدود شده توسط مرورگر، مدیریت حافظه با احتیاط بسیار مهم است - علیرغم اینکه جاوا اسکریپت به صورت زباله جمع آوری شده است. نادیده گرفتن آن آسان است، اما اعلام حتی مقدار کمی از حافظه جدید در یک حلقه بازی می‌تواند هنگام اجرا با فرکانس 60 هرتز به مشکلات مهمی منجر شود. علاوه بر مصرف منابع کاربر در زمینه‌ای که احتمالاً چندوظیفه‌ای انجام می‌دهند، مجموعه‌های زباله بزرگ ممکن است چندین فریم طول بکشد و باعث لکنت قابل توجهی شود. برای جلوگیری از این امر، حافظه حلقه را می توان از قبل در متغیرهای کلاس در زمان اولیه تخصیص داد و در هر فریم بازیافت کرد.

نمای قبل و بعد از نمایه حافظه در طول بهینه سازی پایگاه کد Slow Roads که نشان دهنده صرفه جویی قابل توجه و کاهش نرخ جمع آوری زباله است.
در حالی که استفاده کلی از حافظه به سختی تغییر می کند، حافظه حلقه پیش تخصیص و بازیافت می تواند تاثیر مجموعه زباله های گران قیمت را تا حد زیادی کاهش دهد.

همچنین بسیار مهم است که ساختارهای داده سنگین‌تر، مانند هندسه‌ها و بافرهای داده مرتبط با آنها، به صورت اقتصادی مدیریت شوند. در یک بازی بی نهایت تولید شده مانند Slow Roads، بیشتر هندسه بر روی یک تردمیل وجود دارد - زمانی که یک قطعه قدیمی در فاصله دور افتاد، ساختار داده های آن را می توان برای یک قطعه آینده از جهان، یک طرح، ذخیره و بازیافت کرد. الگوی معروف به ادغام اشیا.

این شیوه‌ها به اولویت‌بندی اجرای ناب، با قربانی کردن برخی از سادگی کد کمک می‌کنند. در زمینه‌های با کارایی بالا، مهم است که به این نکته توجه داشته باشید که چگونه ویژگی‌های راحتی گاهی به نفع توسعه‌دهنده از مشتری قرض می‌گیرند. به عنوان مثال، متدهایی مانند Object.keys() یا Array.map() فوق العاده مفید هستند، اما به راحتی می توان نادیده گرفت که هر کدام یک آرایه جدید برای مقدار بازگشتی خود ایجاد می کنند. درک عملکرد درونی چنین جعبه‌های سیاه می‌تواند به سخت‌تر کردن کد شما و جلوگیری از ضربه‌های عملکردی یواشکی کمک کند.

کاهش زمان بارگذاری با دارایی های تولید شده رویه ای

در حالی که عملکرد زمان اجرا باید دغدغه اصلی توسعه دهندگان بازی باشد، بدیهیات معمول در مورد زمان بارگذاری اولیه صفحه وب همچنان صادق است. کاربران ممکن است هنگام دسترسی آگاهانه به محتوای سنگین، بخشنده‌تر باشند، اما زمان بارگذاری طولانی همچنان می‌تواند برای این تجربه مضر باشد، اگر نه حفظ کاربر. بازی‌ها اغلب به دارایی‌های بزرگی در قالب بافت‌ها، صداها و مدل‌های سه‌بعدی نیاز دارند، و حداقل باید در هر جایی که بتوان جزئیات را در نظر گرفت، به دقت فشرده شوند.

از طرف دیگر، تولید دارایی‌های رویه‌ای برای مشتری می‌تواند در وهله اول از انتقال طولانی مدت جلوگیری کند. این یک مزیت بزرگ برای کاربرانی است که اتصالات آهسته دارند، و به توسعه‌دهنده کنترل مستقیم بیشتری بر نحوه ساخت بازی‌شان می‌دهد – نه فقط برای مرحله بارگذاری اولیه، بلکه در مورد تطبیق سطوح جزئیات برای تنظیمات مختلف کیفیت.

مقایسه ای نشان می دهد که چگونه کیفیت هندسه تولید شده رویه ای در جاده های آهسته می تواند به صورت پویا با نیازهای عملکرد کاربر سازگار شود.

بیشتر هندسه در Slow Roads به صورت رویه‌ای و ساده ایجاد می‌شود، با سایه‌زن‌های سفارشی که چندین بافت را برای ارائه جزئیات ترکیب می‌کنند. اشکال این است که این بافت ها می توانند دارایی های سنگینی باشند، اگرچه فرصت های بیشتری برای صرفه جویی در اینجا وجود دارد، با روش هایی مانند بافت تصادفی که می تواند جزئیات بیشتری را از بافت های منبع کوچک به دست آورد. و در سطح فوق العاده، امکان تولید بافت ها به طور کامل بر روی مشتری با ابزارهایی مانند texgen.js وجود دارد. همین امر حتی در مورد صدا نیز صادق است، با Web Audio API که امکان تولید صدا با گره های صوتی را فراهم می کند.

با بهره مندی از دارایی های رویه ای، تولید محیط اولیه به طور متوسط ​​تنها 3.2 ثانیه طول می کشد. برای بهترین استفاده از اندازه کوچک دانلود در جلو، یک صفحه نمایش ساده به بازدیدکنندگان جدید خوشامد می گوید و شروع گران قیمت صحنه را به بعد از فشار دادن دکمه مثبت به تعویق می اندازد. این همچنین به عنوان یک بافر مناسب برای جلسات برگشتی عمل می کند و انتقال هدر رفته دارایی های بارگذاری شده پویا را به حداقل می رساند.

یک هیستوگرام از زمان بارگذاری که یک اوج قوی را در سه ثانیه اول نشان می دهد که بیش از 60٪ از کاربران را تشکیل می دهد و به دنبال آن کاهش سریعی دارد. هیستوگرام نشان می دهد که بیش از 97 درصد از کاربران زمان بارگذاری کمتر از 10 ثانیه را می بینند.

اتخاذ یک رویکرد چابک برای بهینه سازی دیرهنگام

من همیشه پایه کد برای Slow Roads را تجربی می‌دانستم و به همین دلیل رویکردی بسیار چابک برای توسعه در پیش گرفته‌ام. هنگام کار با یک معماری سیستم پیچیده و به سرعت در حال تکامل، پیش‌بینی اینکه کجا ممکن است تنگناهای مهم رخ دهد دشوار است. تمرکز باید بر روی پیاده‌سازی سریع ویژگی‌های مورد نظر باشد، نه به صورت تمیز، و سپس کار معکوس برای بهینه‌سازی سیستم‌ها در جایی که واقعاً اهمیت دارد. نمایه‌ساز عملکرد در Chrome DevTools برای این مرحله بسیار ارزشمند است و به من کمک کرده است تا برخی از مشکلات اصلی نسخه‌های قبلی بازی را تشخیص دهم. زمان شما به‌عنوان یک توسعه‌دهنده ارزشمند است، بنابراین مطمئن شوید که برای بحث در مورد مشکلاتی که ممکن است بی‌اهمیت یا زائد هستند وقت صرف نکنید.

نظارت بر تجربه کاربر

در حین اجرای همه این ترفندها، مهم است که مطمئن شوید بازی همانطور که انتظار می رود در طبیعت اجرا می شود. گنجاندن طیف وسیعی از قابلیت‌های سخت‌افزاری یکی از جنبه‌های اصلی توسعه هر بازی است، اما بازی‌های وب می‌توانند طیف بسیار گسترده‌تری را که هم دسک‌تاپ‌های سطح بالا و هم دستگاه‌های تلفن همراه دهه‌قدیمی را در بر می‌گیرد، هدف قرار دهند. ساده‌ترین راه برای نزدیک شدن به این موضوع، ارائه تنظیماتی برای تطبیق با محتمل‌ترین تنگناها در پایگاه کد شما - برای کارهایی که با پردازنده گرافیکی و CPU فشرده هستند - همانطور که توسط نمایه‌گر شما فاش شده است.

با این حال، نمایه سازی روی دستگاه شما فقط می تواند موارد زیادی را پوشش دهد، بنابراین بستن حلقه بازخورد با کاربران خود به نحوی ارزشمند است. برای Slow Roads من تجزیه و تحلیل ساده ای را اجرا می کنم که عملکرد را همراه با عوامل زمینه ای مانند وضوح صفحه نمایش گزارش می دهد. این تجزیه و تحلیل ها با استفاده از socket.io به همراه هر بازخورد کتبی که کاربر از طریق فرم درون بازی ارسال می کند به یک باطن اصلی Node ارسال می شود. در روزهای اولیه، این تجزیه و تحلیل‌ها بسیاری از مسائل مهم را شناسایی کردند که می‌توان با تغییرات ساده در UX کاهش داد، مانند برجسته کردن منوی تنظیمات هنگامی که FPS به طور مداوم پایین تشخیص داده می‌شود، یا هشدار دادن به اینکه ممکن است کاربر نیاز به فعال کردن شتاب سخت‌افزاری داشته باشد اگر عملکرد به خصوص ضعیف است.

جاده های آهسته پیش رو

حتی پس از انجام همه این اقدامات، بخش قابل توجهی از پایه پخش کننده باقی می ماند که باید در تنظیمات پایین تری بازی کند – در درجه اول آنهایی که از دستگاه های سبک وزن استفاده می کنند که فاقد GPU هستند. در حالی که طیف تنظیمات کیفیت موجود منجر به توزیع عملکرد نسبتاً یکنواخت می شود، تنها 52 درصد از بازیکنان به بالاتر از 55 فریم در ثانیه دست می یابند.

ماتریسی که با تنظیم فاصله دید در مقابل تنظیم جزئیات تعریف می‌شود و میانگین فریم در ثانیه به دست آمده در جفت‌های مختلف را نشان می‌دهد. توزیع تقریباً به طور مساوی بین 45 و 60 پخش می شود و 60 هدف برای عملکرد خوب است. کاربران در تنظیمات پایین تمایل دارند FPS کمتری نسبت به کسانی که در تنظیمات بالا قرار دارند ببینند، که تفاوت در قابلیت سخت افزار مشتری را برجسته می کند.
توجه داشته باشید که این داده‌ها توسط کاربرانی که مرورگر خود را با شتاب سخت‌افزار غیرفعال اجرا می‌کنند تا حدودی منحرف می‌شوند و اغلب باعث عملکرد پایین مصنوعی می‌شوند.

خوشبختانه، هنوز فرصت های زیادی برای صرفه جویی در عملکرد وجود دارد. در کنار افزودن ترفندهای رندر بیشتر برای کاهش تقاضای GPU، امیدوارم بتوانم با کارگران وب در موازی سازی تولید محیط در کوتاه مدت آزمایش کنم و ممکن است در نهایت نیاز به ادغام WASM یا WebGPU در پایگاه کد را ببینم. هر فضایی که بتوانم آزاد کنم، محیط‌های غنی‌تر و متنوع‌تری را فراهم می‌کند، که این هدف پایدار برای بقیه پروژه خواهد بود.

همانطور که پروژه‌های سرگرمی پیش می‌روند، جاده‌های آهسته یک روش کاملاً رضایت‌بخش برای نشان دادن این است که بازی‌های مرورگر چقدر پیچیده، عملکردی و محبوب هستند. اگر در جلب علاقه شما به WebGL موفق بوده‌ام، بدانید که جاده‌های آهسته از نظر فناوری نمونه‌ای نسبتاً سطحی از قابلیت‌های کامل آن است. من قویاً خوانندگان را تشویق می‌کنم که ویترین Three.js را بررسی کنند و علاقه‌مندان به توسعه بازی‌های وب به طور خاص به انجمن در webgamedev.com خوش آمد می‌گویند.