بازی‌سازی

بهینه‌سازی و انتشار بازی

بازی playable ساخته شد؛ حالا باید روان اجرا شود و به دست بازیکن برسد. بهینه‌سازی عملکرد در Unity، تنظیم build و انتشار روی پلتفرم‌های مختلف را در این مقاله مرور می‌کنیم.

تیم Nova Lab · · 10 دقیقه مطالعه

چرا بهینه‌سازی قبل از انتشار حیاتی است؟

بازی‌ای که روی سیستم توسعه‌دهنده روان است ممکن است روی موبایل یا PC ضعیف lag داشته باشد. بازیکن امروز انتظار frame rate پایدار و زمان بارگذاری کوتاه دارد؛ اگر بازی کند باشد، حتی با گیم‌پلی خوب، uninstall یا abandon می‌شود. بهینه‌سازی نه luxury بلکه بخشی از تجربه محصول است.

در Unity، مشکلات عملکرد معمولاً از منابع گرافیکی سنگین، physics بیش از حد، GC allocation در Update، draw call زیاد و lighting نادرست ناشی می‌شوند. خبر خوب: بیشتر این موارد با ابزارهای داخلی Unity قابل شناسایی و اصلاح هستند — اگر methodology درست را از ابتدا بشناسید.

Nova Lab در بخش پایانی دوره unity-game-dev به بهینه‌سازی و build می‌پردازد، زیرا دانشجویی که فقط prototype می‌سازد اما نمی‌داند چطور آن را publish کند، نیمی از مسیر را طی کرده. هدف: بازی قابل نصب، قابل بازی و قابل نشان دادن در portfolio.

تفاوت بین «روی لپ‌تاپ من خوب بود» و «روی گوشی دوستم crash کرد» درس کلاسیک انتشار است. تست روی دستگاه‌های متنوع — حتی ارزان — قبل از release از reputational damage جلوگیری می‌کند و نشان می‌دهد شما مثل توسعه‌دهنده حرفه‌ای فکر می‌کنید.

لیست ساده «قبل از انتشار» بسازید: بدون crash در اولین launch، صدا و کنترل درست، متن خوانا، حجم معقول و یک مسیر مشخص برای بازخورد. Nova Lab این checklist را به‌عنوان بخش تحویل پروژه پایانی استفاده می‌کند.

Profiler و شناسایی bottleneck

Unity Profiler ابزار اصلی تحلیل عملکرد است. CPU Usage نشان می‌دهد کدام اسکریپت یا سیستم زمان می‌برد؛ GPU نشان می‌دهد rendering کجا سنگین است؛ Memory به leak و allocation اشاره می‌کند. قبل از هر بهینه‌سازی تصادفی، Profiler را باز کنید و bottleneck واقعی را پیدا کنید — اغلب با چیزی که حدس زدهید متفاوت است.

برای موبایل، Profiler را روی دستگاه واقعی یا با Unity Remote متصل کنید. شبیه‌سازی در Editor دقیق نیست. frame time هدف برای ۶۰ FPS حدود ۱۶.۶ میلی‌ثانیه و برای ۳۰ FPS حدود ۳۳ میلی‌ثانیه است. اگر از این بیشتر است، باید بفهمید کدام بخش مقصر است.

در تمرین Nova Lab، دانشجویان یک صحنه با مشکل عملکرد عمدی را با Profiler تحلیل می‌کنند و گزارش کوتاهی می‌دهند: مشکل، علت، راه‌حل. این مهارت در تیم‌های حرفه‌ای روزانه استفاده می‌شود و تفاوت بین «فکر می‌کنم کند است» و «می‌دانم چرا کند است» را مشخص می‌کند.

Frame Debugger برای مشکلات rendering مفید است: هر draw call را می‌بینید و می‌فهمید چرا GPU busy است. ترکیب Profiler + Frame Debugger معمولاً ۸۰٪ مشکلات عملکرد رایج در پروژه‌های آموزشی را پوشش می‌دهد.

هنگام profiling، یک سناریوی ثابت replay کنید: همان مسیر حرکت، همان combat. بدون سناریوی ثابت، مقایسه قبل و بعد از بهینه‌سازی گمراه‌کننده می‌شود. در Nova Lab این روش «baseline + change» را در گزارش عملکرد تمرین می‌دهیم.

بهینه‌سازی گرافیک و rendering

کاهش draw call با batching، استفاده از atlas برای sprite، محدود کردن overdraw و انتخاب shader مناسب تأثیر زیادی دارد. برای 3D، LOD (Level of Detail) برای مدل‌های دور، occlusion culling و تنظیم shadow distance مهم هستند. Quality Settings در Unity به شما اجازه می‌دهد سطوح مختلف گرافیک برای دستگاه‌های ضعیف و قوی تعریف کنید.

Textureها را با اندازه مناسب import کنید — texture ۴K برای آیکون UI تلفن اشتباه است. فرمت compression بسته به پلتفرم (Android، iOS) متفاوت است. Lightmapping برای محیط‌های static به‌جای realtime lighting همه جا، در بسیاری از بازی‌های موبایل انتخاب هوشمند است.

قانون عملی: هر asset گرافیکی باید «دلیل وجود» داشته باشد. اگر visual تأثیری روی gameplay ندارد و performance می‌خورد، ساده‌اش کنید یا حذف کنید. بازی indie موفق اغلب با art style ساده اما coherent عملکرد بهتری از بازی شلوغ با assetهای ناهماهنگ دارد.

URP (Universal Render Pipeline) برای بسیاری از پروژه‌های موبایل و indie انتخاب پیش‌فرض مدرن Unity است. در Nova Lab با تنظیمات URP پایه آشنا می‌شوید: shadow quality، render scale و post-processing فقط وقتی لازم است فعال شوند.

کد و حافظه: GC و allocation

در Unity، allocation در hot path — مثل Update هر frame — می‌تواند GC spike ایجاد کند و frame drop ناگهانی بسازد. از ایجاد object جدید در Update (مثل string concatenation یا new List) پرهیز کنید. object pooling برای bullet، enemy و particle رایج است. struct به‌جای class در موارد مناسب می‌تواند allocation را کم کند.

Coroutine و event برای timing بهتر از polling بی‌پایان است. Find و GetComponent در Update ممنوع — در Awake یا Start cache کنید. این قوانین ساده اما اگر از روز اول رعایت شوند، debug عملکرد در انتها بسیار کمتر می‌شود.

StringBuilder برای به‌روزرسانی UI متنی مکرر (مثل score) از concatenation معمولی بهتر است. برای prototype ساده شاید تفاوت کم باشد، اما در build موبایل با UI پر از متن زنده، allocation کمتر محسوس است.

Memory Profiler (یا package مربوطه) برای پیدا کردن leak و assetهای بارگذاری شده اما استفاده نشده مفید است. پس از هر session بازی، memory باید به سطح پایدار برگردد؛ اگر مدام بالا می‌رود، leak دارید. Nova Lab در code review پروژه‌های پایانی این موارد را چک می‌کند.

Physics هم می‌تواند bottleneck باشد: colliderهای پیچیده، rigidbody زیاد و fixed timestep نامناسب. ساده‌تر کردن collision mesh و کاهش تعداد dynamic rigidbody اغلب بدون تغییر visual نتیجه محسوس می‌دهد.

تنظیمات Build و Player Settings

قبل از build، پلتفرم هدف را در Build Settings انتخاب کنید. Player Settings شامل نام bundle، آیکون، orientation (برای موبایل)، scripting backend (IL2CPP برای موبایل و کنسول رایج است) و سطوح API می‌شود. هر پلتفرم checklist خاص خود را دارد — Android نیاز به keystore، iOS نیاز به Apple Developer account دارد.

Development Build با Autoconnect Profiler برای تست نهایی قبل از release build مفید است. Release build باید بدون debug overhead و با optimization فعال باشد. Scenes در build را مدیریت کنید — فقط sceneهای لازم را include کنید تا حجم و زمان load کم شود.

در دوره Nova Lab، دانشجویان حداقل یک build PC (Windows) و در صورت امکان Android APK تحویل می‌دهند. تجربه نصب بازی روی دستگاه دیگر — نه فقط Play در Editor — درس مهمی درباره مسیر واقعی تا بازیکن است.

حجم build را با compression، حذف unused assets و split APK/AAB برای Android مدیریت کنید. کاربر موبایل حجم بالا و نصب طولانی را کمتر تحمل می‌کند؛ برای اولین انتشار، سبک‌تر بهتر از feature-packed و سنگین است.

انتشار روی پلتفرم‌های مختلف

برای PC، انتشار مستقیم (وب‌سایت شخصی، itch.io، Steam) مسیرهای رایج هستند. Steam نیاز به فرآیند review و Steamworks دارد؛ itch.io برای indie و prototype بسیار accessible است. برای موبایل، Google Play و App Store درگاه‌های اصلی هستند — هر کدام policy، age rating و metadata خاص می‌خواهند.

قبل از submit، store listing آماده کنید: توضیح کوتاه، screenshotهای واقعی gameplay، آیکون با اندازه‌های استاندارد و در صورت نیاز trailer کوتاه. بازی crash نکند در اولین launch — تست روی چند دستگاه یا emulator. rejection اولیه در storeها شایع است؛ feedback را بخوانید و اصلاح کنید.

برای بازار ایران، انتشار بین‌المللی ممکن است محدودیت پرداخت و دسترسی داشته باشد؛ اما build و portfolio محلی هم ارزش دارد. بسیاری از دانشجویان Nova Lab بازی را برای نمایش در کلاس، رویداد یا شبکه‌های اجتماعی منتشر می‌کنند — این هم شروع معتبر انتشار است.

صفحه landing ساده با لینک دانلود، توضیح کوتاه و gameplay GIF برای انتشار مستقل کافی است. حتی بدون store، شما workflow «ساخت → build → توزیع» را کامل کرده‌اید — همان چیزی که کارفرما در پوزیشن junior می‌خواهد ببیند.

برای itch.io یا انتشار مستقیم، فایل README کوتاه با نیازمندی‌های سیستم و نحوه اجرا به تجربه کاربر کمک می‌کند. این جزئیات کوچک حرفه‌ای‌گری شما را نشان می‌دهد و از سوالات تکراری جلوگیری می‌کند.

نگهداری، آپدیت و مسیر بعد از انتشار

انتشار نقطه پایان توسعه اولیه نیست. bug report از بازیکن، analytics (با رعایت privacy) و نظرات به شما می‌گویند کجا patch یا content update لازم است. version numbering منظم (1.0.1 برای bugfix) اعتماد بازیکن را حفظ می‌کند.

برای بازی‌های live، بهینه‌سازی مداوم با هر آپدیت content مهم است — asset جدید ممکن است performance قبلی را خراب کند. regression test: بعد از هر تغییر بزرگ، Profiler را دوباره اجرا کنید. این habit در استودیوهای حرفه‌ای embedded است.

Changelog عمومی برای بازیکنان کوچک هم مفید است: «نسخه 1.0.1 — رفع crash در سطح دوم» اعتماد می‌سازد. برای portfolio، لینک به buildهای مختلف نشان می‌دهد شما محصول را زنده نگه می‌دارید.

اگر دوره unity-game-dev را در Nova Lab گذرانده‌اید، شما prototype ساخته، بهینه کرده و build گرفته‌اید — یعنی چرخه کامل را یک بار دیده‌اید. قدم بعدی: پروژه شخصی بزرگ‌تر، شرکت در game jam، یا تخصص در یک حوزه (UI، networking، shader). بهینه‌سازی و انتشار مهارت‌هایی هستند که با هر پروژه Unity عمیق‌تر می‌شوند؛ هر بازی منتشرشده خط بعدی resume شماست.

community Discord یا گروه دانشجویان Nova Lab منبع خوبی برای گزارش bug و ایده آپدیت بعد از انتشار اول است. نگه داشتن حلقه feedback حتی برای بازی کوچک، شما را در mindset live product نگه می‌دارد — تفاوت بین کسی که یک بار بازی ساخته و کسی که در حال ساخت محصول است.

سوالات متداول

اول بهینه‌سازی کنم یا اول feature کامل؟

ابتدا gameplay و featureهای اصلی را برای prototype بسازید، سپس قبل از انتشار بهینه‌سازی کنید. بهینه‌سازی زودهنگام بدون داده Profiler اغلب وقت تلف می‌کند. در Nova Lab بهینه‌سازی در فاز نهایی پروژه آموزش داده می‌شود.

هدف frame rate برای موبایل چیست؟

۳۰ FPS پایدار برای بسیاری از بازی‌های موبایل قابل قبول است؛ ۶۰ FPS برای اکشن سریع بهتر است. مهم‌تر از عدد مطلق، ثبات frame time است — drop ناگهانی تجربه را خراب می‌کند.

برای انتشار در Google Play چه نیاز دارم؟

حساب Google Play Developer (هزینه ثبت‌نام یک‌باره)، APK یا AAB signed، آیکون و screenshot، توضیح store و رعایت policyهای محتوا. برای بازی‌های ساده بدون IAP، فرآیند معمولاً straightforward است.

IL2CPP چیست و چرا مهم است؟

IL2CPP backend کد managed را به C++ native تبدیل می‌کند و برای build موبایل و کنسول معمولاً استفاده می‌شود. عملکرد بهتر و سازگاری با platformهایی که JIT ندارند دلایل اصلی انتخاب آن در release build هستند.