موتور ولف (Wolf Engine)، نسل جدید موتور بازی سازی پرشین، زیرساختی بود که از سال ۲۰۱۶ روی زبان سی / سی پلاس پلاس توسعه یافت. در ابتدا هدف اصلی موتور بازی سازی پرشین تنها ساخت بازی بود. این موتور محصول شرکت بازی پرداز توانسته بود در سال ۱۳۹۰ به عنوان یکی از برترین های فناوری بازی های رایانه ای در پنجمین جشنواره و نمایشگاه رسانه های دیجیتال برگزیده شود.
پرشین توسط “DirectX9” و زبان “#C” توسعه یافته بود. به همین دلیل در سال ۲۰۱۶ با شروع تحولاتی که در نسل جدید API های گرافیکی رخ داد، نیاز بود پرشین را مجددا بازنویسی کنیم و از این رو پروژه Wolf متولد شد.
هدف Wolf حفظ ویژگی های پرشین و مهاجرت به API های گرافیکی جدید بود. در این مهاجرت در اولین نسخه Wolf، از API گرافیکی“DirectX11” و در نسخه دوم از API های گرافیکی“DirectX12“,“Vulkan” و“Apple Metal” بصورت کراس پلتفرم پشتیبانی شد. این انجین بصورت موازی در توسعه زیرساخت پروژهایی نظیر PlayOut، CG، گیم، شبیه ساز سه بعدی Falcon و کنسول بازی ابری پلی پاد بکار گرفته شد. Wolf طی سال های ۲۰۱۶ تا ۲۰۲۱ بصورت اوپن سورس بر روی گیت هاب عرضه شد و مورد استقبال جامعه اوپن سورس قرار گرفت. این موتور در سال ۲۰۲۱ بنا به درخواست سرمایه گذار خارجی موقتا بصورت کلوز سورس درآمد.
چرا توسعه به زبان های سی و سی پلاس پلاس ؟
در حین توسعه پرشین با چالش های بسیاری در زبان برنامه نویسی«مدیریت شده» روبرو شدیم. البته در بسیاری از بخش ها با نوشتن Wrapper هایی بر روی لایبرری های سی پلاس پلاسی توانستیم مشکلات زبان #C را حل کنیم. اگر تجربه برنامه نویسی دارید میدانید که زبان های برنامه نویسی سیستمی به دو دسته«مدیریت شده» (managed) و«غیر مدیریت شده» (unmanaged یا native) تقسیم بندی میشوند. زبان های«مدیریت شده» نظیر سی شارپ، جاوا، کاتلین و … بر پایه یک ماشین مجازی یا محیط ران تایم عمل میکنند (dotNet، JVM یا …) و مدیریت حافظه در این زبان ها توسط GC انجام میشود. وظیفه GC یا Garbage Collector کنترل حافظه بصورت اوتومات میباشد. این زبان ها برای کار با سخت افزار و سیستم های بلادرنگ (real-time) گزینه مناسبی نیستند. از طرفی زبان های native نظیر C/C++/Rust پرفورمنس بالایی ارایه میکنند اما مدیریت حافظه در آنها توسط کد برنامه نویس باید کنترل شود و این مستلزم شناخت خوب تیم برنامه نویس از ساختار حافظه است. (در راستای بحث GC بد نیست این مقاله را مطالعه فرمایید که چرا دیسکورد از زبان Go به زبان Rust مهاجرت کرد)
Wolf هم همانند تمامی موتور های بازی سازی مستقیما با“GPU“ سر و کار دارد و با توجه به آنکه بخش زیادی از لایبرری های مرتبط و API های گرافیکی بر روی زبان های سی و سی پلاس پلاس ارایه شده اند، لذا تصمیم بر آن شد که توسعه Wolf با ++C آغاز شود.
Wolf توسط این دو زبان توسعه یافت. همچنین از آن بصورت کراس پلتفرم در توسعه زیرساخت و اپلیکیشن های کنسول بازی ابری پلی پاد استفاده شد. این دو زبان native اگرچه پرفورمنس بالایی دارند اما یک مشکل بزرگ هم دارند و آن unsafe بودنشان است و این عدم ایمنی حافظه میتواند روی امنیت، ثبات و کیفیت ریلیز های محصولات تاثیر منفی بگذارد.
چرا Wolf به زبان Rust مهاجرت کرد؟
مت میلر (Matt Miller) ، مهندس امنیت مایکروسافت، در کنفرانس امنیتی BlueHat اشاره کرد که در طول ۱۲ سال گذشته، حدود ۷۰ درصد از تمامی پچ های مایکروسافت به رفع اشکالات ایمنی حافظه مربوط بوده است. این مساله در گزارش مرکز پاسخگویی امنیتی مایکروسافت (MSRC) هم مورد تایید قرار گرفت.

تیم امنیت گوگل کرومیوم هم در گزارشی مشابه اعلام کرد حدود ۷۰ درصد از اشکالات امنیتی به اشتباهات اشاره گر های زبان C و ++C منتهی میشوند. ما هم در پروسه توسعه ولف و پروژه های مبتی بر ولف با این مشکلات روبرو شدیم. با وجود Code Review در توسعه ولف و استفاده از Memory Sanitizer ها، همچنان رفع مشکلاتی از قبیل Access Violation Memory، Use-after-free و یا Dangling Pointers هزینه بالایی داشت. همچنین کمبود نیروی متخصص در حوزه برنامه نویس native و low level در شرایط کنونی، ما را بر آن داشت تا بصورت جدی تری شرایط مهاجرت به زبان Rust را بررسی کنیم. انتظار داشتیم اگر این مهاجرت به درستی صورت بگیرد هزینه توسعه و رفع مشکلات به مراتب کاهش پیدا کند.

Rust همانند C و ++C یک زبان برنامه نویسی سیستمی همه منظوره است که به منظور حفظ عملکرد و ایمنی بویژه برای Concurrency در سال ۲۰۱۱ توسط Graydon Hoare در Mozila Research طراحی شد. راست از نظر عملکرد شبیه سی و سی پلاس پلاس میباشد با این تفاوت که میتواند ایمنی حافظه را با استفاده از ویژگی borrow checker در حین کامپایل بررسی و تضمین کند. این ویژگی کمک میکند که دیگر نیازی به GC یا Memory Sanitizer ها نداشته باشید و یا نگران عملکرد اشاره گر های حافظه نباشید، اگرچه باید ساختار حافظه را حتما بشناسید و بر مبنای منطقborrow checker و ownership کد خود را کامپایل کنید که کار ساده ای هم نیست اما زمانی که پروژه شما بیلد شود خیالتان از عملکرد آن آسوده خواهد بود.
همانطور که در تصویر بالا مشاهده میکنید عملکرد Rust نزدیک به زبان های ++C و C میباشد. Rust از سال ۲۰۱۶ تاکنون بصورت پیوسته در نظرسنجی “Stack Overflow” به عنوان «محبوب ترین زبان برنامهنویسی» انتخاب شده است، البته لازم به ذکر است در نظرسنجی سال ۲۰۲۱ این زبان تنها توسط ۷ درصد از رای دهندگان استفاده شده بود. این مطلب حاکی از آن است که بزرگترین چالش این زبان، نحوه مهاجرت از کدهای ++C/C به Rust است؛ که در پست آتی پلی پاد تی وی به چالش های این مهاجرت در موتور ولف اشاره خواهیم کرد.