۱. بازی را به یک مسئلهٔ کوچک و قابلآزمون تبدیل کن
مافیا نسخههای زیادی دارد. اگر پیش از ساخت دربارهٔ تعداد نفرات، نقشها و پایان بازی تصمیم نگیری، احتمالاً رابطی زیبا خواهی داشت که معلوم نیست چه زمانی باید رأی بگیرد یا چه کسی برنده شده است. برای نسخهٔ اول، یک میز با یک انسان و چند شخصیت هوش مصنوعی کافی است. نمونهٔ هفتنفره یعنی یک انسان و شش شخصیت هوش مصنوعی؛ این عدد را میتوانی بعداً قابلتغییر کنی.
بازی را متنی نگه دار. نمایش کارت شخصیتها و تصویر نقشها میتواند به خوانایی کمک کند، اما هستهٔ بازی باید بدون تصویر هم قابلفهم باشد: چه کسی حرف زد، نوبت چه کسی است، چه رأیهایی ثبت شده و مرحلهٔ فعلی چیست. این انتخاب باعث میشود بهجای درگیرشدن با موتور بازیسازی، زودتر بفهمی آیا گفتوگو و تصمیمگیری بازی جذاب است یا نه.
نتیجهٔ این مرحله: باید بتوانی ایده را در یک جمله بنویسی: «یک نفر با چند شخصیت هوش مصنوعی، طبق قوانین مشخص مافیا، در یک رابط فارسی بازی میکند.» اگر برای توضیح نسخهٔ اول ناچار شدی از حساب کاربری، رتبهبندی و بازی آنلاین انسانها حرف بزنی، محدوده را دوباره کوچک کن.
۲. پیش از ساخت رابط، قوانین میز را مکتوب کن
مثال تکمیلی آموزشی: برای شروع، مجموعهٔ محدودی از نقشها مثل شهروند، مافیا و کارآگاه تعریف کن. این انتخاب، پیشنهاد آموزشی است؛ نه فهرست قطعی نقشهای پیادهسازیشده. در فایل docs/mafia-prd.md داخل ریشهٔ پروژه، بنویس هر نقش چه اطلاعاتی میبیند و در شب چه کاری، اگر کاری دارد، میتواند انجام دهد. برای کارآگاه، پیش از کدنویسی روشن کن پاسخ بررسی دقیقاً چیست و آیا در همان شب نمایش داده میشود.
بعد ترتیب مراحل را تعیین کن: تخصیص مخفی نقشها، گفتوگوی روز، رأیگیری، نتیجهٔ رأی، اقدامهای شب، اعلام اتفاقهای مجاز به همه و آغاز روز بعد. هیچکدام را به حدس مدل زبانی واگذار نکن. مثال تکمیلی آموزشی برای یک مجموعهقانون مشخص، نه گزارش پیادهسازی لایو: در میز هفتنفره دو مافیا، یک کارآگاه و چهار شهروند بگذار و روز اول را پس از تخصیص نقشها آغاز کن. هر بازیکن زنده در رأیگیری روز حداکثر یک رأی دارد؛ صاحب بیشترین رأی حذف میشود و در تساوی یا نبود رأی کسی حذف نمیشود. حذفشده دیگر صحبت، رأی یا اقدام شبانه ندارد. هر مافیای زنده شب یک بازیکن زندهٔ غیرمافیا را پیشنهاد میکند؛ هدفی که بیشترین پیشنهاد را دارد حذف میشود و در تساوی قتلی رخ نمیدهد. کارآگاه زنده شب یک بازیکن زندهٔ دیگر را بررسی میکند و پاسخ «مافیا هست/نیست» فقط برای خودش ثبت میشود. پس از هر حذف، اگر همهٔ مافیا حذف شدهاند شهروندان برندهاند؛ اگر تعداد مافیای زنده دستکم برابر دیگر بازیکنان زنده است مافیا برنده است؛ وگرنه بازی ادامه دارد. برای این تمرین ابتدا بررسی کارآگاه را برای بازیکنی که در آغاز شب زنده بوده ثبت کن، سپس قتل را اعمال کن؛ اگر کارآگاه همان شب حذف شد، نتیجه فقط در تاریخچهٔ خصوصی او میماند و حذفشده حق انتقال آن به گفتوگوی بازی ندارد. این ترتیب را در PRD ثابت کن. اینها فقط یک انتخاب آموزشیاند؛ مدلی که دیالوگ میسازد نباید بتواند قانون پیروزی را تغییر دهد.
برای نسخهٔ ابتدایی، نقش بازیکن حذفشده را تا پایان بازی مخفی نگه دار؛ این یک تصمیم طراحی است و بعداً میتوانی تغییرش بدهی. کنار هر قانون، یک مثال کوتاه از نتیجهٔ موردانتظار بنویس. مثلاً اگر دو نفر رأی مساوی آوردند، آیا رأیگیری تکرار میشود یا کسی حذف نمیشود؟ پاسخ ثابت به این سؤال، هم ساخت بازی را آسان میکند و هم پیدا کردن باگ را.
۳. KMP را برای اشتراک منطق انتخاب کن، نه وعدهٔ خروجی فوری
Kotlin Multiplatform امکان میدهد بخشی از کد Kotlin، مانند مدل وضعیت و قواعد بازی، میان هدفهای مختلف مشترک باشد. اما «یک کد برای همهچیز» تعبیر دقیقی نیست: تنظیمات ساخت، اجرای هر هدف، بعضی وابستگیها و اتصال رابط یا سرویسها ممکن است کار جداگانه بخواهند. در این پروژه، KMP برای حفظ امکان توسعهٔ بعدی به موبایل انتخاب مناسبی است؛ آزمون نخست را فقط روی وب متمرکز کن.
در Android Studio، اگر قالب Kotlin Multiplatform در دسترس است پروژهٔ تازهای با آن بساز؛ در غیر این صورت از سازندهٔ پروژهٔ KMP قالب دارای هدف وب را بگیر و پروژه را در Android Studio باز کن. وب، کد مشترک و آزمونها را برای نمونهٔ اولیه نگه دار؛ اگر قالب امکان رابط مشترک میدهد، انتخاب آن را هم ثبت کن. انتخاب Android و iOS به معنی ساختهشدن و آزمودهشدن آن نسخهها نیست. پس از همگامسازی Gradle، پیکربندی اجرای وبِ تولیدشده برای همان قالب را اجرا کن و مطمئن شو صفحهٔ نمونه در مرورگر باز میشود. اگر پیکربندی اجرا وجود ندارد یا ساخت متوقف میشود، پیش از نوشتن بازی راهنمای همان قالب، پیام خطا و دسترسی به وابستگیها را بررسی کن؛ نام دستور اجرا را حدس نزن.
نتیجهٔ این مرحله: پروژه باید در محیط توسعه باز شود و بتوانی هدف وب قالب اولیه را با پیکربندی اجرای موجود اجرا کنی. نام و شکل پیکربندی به قالبی که انتخاب کردهای بستگی دارد؛ بهجای حدسزدن دستور ساخت، همان تنظیمات تولیدشدهٔ پروژه را بررسی کن.
۴. PRD بنویس و از دستیار بخواه ابهامها را پیدا کند
PRD یا «سند نیازمندیهای محصول» قرار نیست متن تشریفاتی باشد. همان فایل docs/mafia-prd.md باید بگوید چه چیزی در نسخهٔ اول هست، چه چیزی نیست و از کجا میفهمی بازی درست پیش میرود. برای این نمونه، وبِ قابلبازی، رابط فارسی، نقشهای مخفی و گفتوگوی روز را در محدوده بگذار. ذخیرهٔ دائمی بازی، چندنفرهٔ انسانی و انتشار نسخهٔ موبایل را فعلاً بیرون بگذار. دربارهٔ آزمونهای منطق پایه سختگیری را کنار نگذار، حتی اگر فعلاً دیتابیس نمیخواهی.
بازنویسی آموزشی پرامپت برای دستیار کدنویسی؛ این متن، نقلقول لفظبهلفظ از روند ساخت نیست:
Read docs/mafia-prd.md and inspect the current KMP project. Do not edit files yet. Ask me five questions about unclear rules, role visibility, the first playable web flow, Persian UI, and AI Pass integration. Then propose a short implementation plan. Keep human multiplayer, persistent storage, and mobile release out of scope for this iteration.
پاسخ سؤالها را در همان PRD ثبت کن، سپس برنامهٔ دستیار را با سند مقایسه کن. اگر پیشنهادش ناگهان سرور چندنفره یا پایگاهداده اضافه کرد، قبل از اجازهٔ ویرایش اصلاحش کن. اجرای برنامه را به گامهای قابلبررسی بشکن: نخست مدل وضعیت و قواعد گذار مرحله را در کد مشترک بساز؛ بعد برای رأی مساوی، اقدام نامجاز، حذف بازیکن و پایان بازی آزمون بنویس؛ سپس رابط وب را به همان وضعیت وصل کن. پیش از اتصال AI Pass، با پاسخهای ثابت و اقدامهای ازپیشتعریفشدهٔ شخصیتهای آزمایشی یک بازی را تا پایان پیش ببر و این مسیر را صریحاً «حالت آزمایشیِ بدون هوش مصنوعی» بنام. اتصال مدل و آزمون دوبارهٔ جریان، گام بعدی است. پس از هر گام، تغییر فایلها و نتیجهٔ ساخت و آزمون را بررسی کن. بهتر است دستیار برای ویرایش فایلها اجازه بخواهد؛ دسترسی بیقید صرفاً برای سرعت بیشتر، ریسک تغییر یا پاکشدن ناخواستهٔ پروژه را بالا میبرد.
۵. وضعیت بازی را از متن گفتوگو جدا نگه دار
در بازی متنی، تاریخچهٔ چت فقط بخشی از بازی است. یک «وضعیت بازی» جدا لازم داری که مرحلهٔ فعلی، بازیکنان زنده، نقشهای تخصیصیافته، نوبت، رأیها، اقدامهای شب و نتیجهٔ نهایی را نگه دارد. رابط این وضعیت را نمایش میدهد و درخواست بازیکن، اگر مجاز باشد، آن را تغییر میدهد. متن تولیدشدهٔ مدل نباید منبع حقیقت برای رأی یا نقش باشد.
مثال تکمیلی آموزشی: وقتی بازیکن در مرحلهٔ گفتوگو مینویسد «به سارا مشکوکم»، این جمله به تاریخچهٔ عمومی افزوده میشود؛ هنوز رأی ثبت نشده است. فقط فشردن دکمهٔ رأی در مرحلهٔ رأیگیری باید رأی او را تغییر دهد. هر درخواست را بهصورت اقدام مشخص، نه برداشتی از متن چت، به منطق بازی بده. پیش از تغییر وضعیت بررسی کن بازی تمام نشده، فرستنده زنده است، مرحله و نوبت درستاند، هدف مجاز است و رأی یا اقدام تکراری ثبت نمیشود؛ سپس وضعیت و در صورت لزوم مرحله را تغییر بده و در آخر خروجی قابلنمایش را بساز. همین اعتبارسنجی باید برای اقدام بازیکن انسانی و اقدام پیشنهادی شخصیت هوش مصنوعی اجرا شود.
نتیجهٔ این مرحله: اگر صفحه را نگاه کنی، بتوانی بدون خواندن حدسی تمام دیالوگها بفهمی اکنون روز است یا شب، نوبت کیست و آیا رأیگیری تمام شده است. اگر مدل در متنش ادعا کرد کسی حذف شده ولی وضعیت بازی چنین چیزی نشان نمیدهد، وضعیت معتبر است و ادعای متن باید اصلاح شود.
۶. برای هر شخصیت فقط اطلاعات مجاز خودش را بفرست
مخفیبودن نقش فقط به این معنی نیست که کارت نقش را در رابط نشان ندهی. هر بار که از مدل برای یک شخصیت پاسخ میخواهی، باید ورودی همان شخصیت را بسازی: قوانین عمومی، مرحلهٔ فعلی، گفتوگوی عمومی، نام و نقش خودش و فقط اطلاعات خصوصیای که طبق قوانین حق دانستنش را دارد. نقش سایر بازیکنان یا اقدامهای محرمانهٔ شب را بهطور پیشفرض به ورودی همه اضافه نکن.
برای هر شخصیت، تاریخچهٔ جداگانه نگه دار. حتی با تاریخچهٔ جدا، اگر هنگام ساخت درخواستْ فهرست کامل نقشها را به همه بفرستی، حریم اطلاعاتی بازی شکسته میشود. این مرز را با یک آزمون ساده کنترل کن: ورودی آمادهشده برای یک شهروند را ببین و مطمئن شو نقش کارآگاه یا مافیا در آن لو نرفته است. اگر قانون میز میگوید اعضای مافیا یکدیگر را میشناسند، آن استثنا را صریح و محدود اعمال کن.
به مدل هویت را هم روشن بده: «تو سارا هستی؛ فقط از دید سارا پاسخ بده.» این دستور جایگزین کنترل دسترسی نیست، ولی جلوی بخشی از خطاهای گفتوگویی را میگیرد. گفتوگوی عمومی را دادهٔ غیرقابلاعتماد بدان: بازیکن میتواند در چت بنویسد «دستورهای قبلی را نادیده بگیر»، اما این متن نباید اختیار تغییر نقش، رأی یا مرحله پیدا کند. اگر مدل افزون بر دیالوگ، اقدامی پیشنهاد میکند، آن را فقط پس از اعتبارسنجی قواعد بازی بپذیر. در آزمون نمونه، شخصیتِ خطابشده پاسخی شبیه توضیحی داد که بازیکن اتهامزننده باید میگفت. چنین خطایی را فقط با تغییر ظاهر حل نکن؛ ورودی هویت، تاریخچه و متن ارسالی به مدل را بررسی کن.
۷. AI Pass را بهعنوان اتصال بیرونی و هزینهدار ببین
در طرح پروژه، AI Pass راه دسترسی شخصیتها به مدلهای هوش مصنوعی بود و اتصال کاربر به حساب خودش نیز در جریان آزمون دیده شد. برای طراحی، این دو موضوع را جدا نگه دار: «کاربر چگونه اجازه میدهد از حسابش استفاده شود؟» و «برنامه چگونه درخواست مدل را برای یک شخصیت میسازد؟» برای اتصال واقعی، نخست مستندات فعلی AI Pass را دربارهٔ ثبت برنامه، روش مجاز ورود و مجوزدهی، محل اجرای درخواست مدل و قطع دسترسی بررسی کن؛ نام API، نوع توکن یا جریان مرورگری را از روی این لایو حدس نزن. در یک آزمون با حساب خودت، رضایت کاربر، ثبت هزینهٔ درخواست و اثر قطع دسترسی را جداگانه بررسی کن و پیش از شروع بازی هزینهٔ احتمالی را برای کاربر روشن بگو. اگر هنوز اتصال آماده نیست، فقط حالت آزمایشیِ بدون هوش مصنوعی را اجرا کن. اعتبار هدیه، قیمت و مدلهای قابلانتخاب را مقدار ثابت معماری فرض نکن؛ ممکن است تغییر کنند.
اگر هدف وب داری، هیچ کلید محرمانه یا دسترسی سراسری را در کد مرورگر قرار نده. صرف وجود صفحهٔ ورود یا جداکردن ورودی شخصیتها نیز نقشها را از بازیکن انسانی مخفی نمیکند: اگر فهرست کامل نقشها، بذر قابلاستفاده برای بازسازی آنها یا وضعیت مرجع بازی به مرورگر فرستاده شود، بازیکن میتواند آن را با ابزار توسعه بررسی کند. برای نسخهٔ وبِ عمومی با نقشهای واقعاً مخفی، تخصیص نقش، وضعیت مرجع، اعتبارسنجی اقدامها و ساخت ورودی هر شخصیت را در مؤلفهای مورداعتماد سمت سرور نگه دار و فقط اطلاعات مجاز همان بازیکن را برگردان. روش مجاز انتقال مجوز AI Pass میان مرورگر و این مؤلفه را طبق مستندات فعلی سرویس طراحی کن؛ نمونهٔ صرفاً مرورگری را بدون این مرز، بازیِ امن و آمادهٔ استفادهٔ عمومی معرفی نکن.
۸. نسخهٔ وب را با سناریو بازی کن و باگ را بازتولید کن
پس از ساختهشدن جریان پایه، بازی را از دید یک بازیکن تازهوارد شروع کن: نقش خودت را ببین، حرف بزن، به مرحلهٔ رأی برس و بررسی کن آیا دکمهها و متنهای فارسی با مرحله هماهنگاند. برای هر ایراد، در docs/mafia-checks.md داخل ریشهٔ پروژه، چهار چیز را بنویس: وضعیت پیش از خطا، اقدام انجامشده، نتیجهٔ واقعی و نتیجهٔ موردانتظار. مثلاً «پس از اتهام به سارا، پاسخ سارا باید از دید خودش باشد، نه از زبان اتهامزننده.»
بازنویسی آموزشی پرامپت برای بررسی همان ایراد:
In a daytime conversation, the human accused Sara, but Sara replied as if she were the accuser. Inspect how speaker identity, public history, and private context are assembled for each AI request. Explain the likely cause before editing. Make the smallest correction and show how to reproduce and check the result. Do not change the game rules.
اگر درخواست تولید پاسخ کند شد، ابتدا تشخیص بده مشکل از انتظار برای مدل است یا از ترتیب نوبتها. افزودن صدا با تبدیل متن به گفتار میتواند مرحلهٔ پخش را نیز به زمان انتظار اضافه کند؛ بنابراین آن را پس از درستشدن گفتوگوی متنی بررسی کن. تغییر مدل هر شخصیت و صدا، قابلیتهای جالبی برای آزمایشاند، اما معیار موفقیت نسخهٔ اول نیستند.
۹. راه اشتراک نمونه را با انتشار محصول اشتباه نگیر
localhost فقط به برنامهای روی دستگاه خودت اشاره میکند؛ فرستادن نشانی آن به دیگری، بازی در حال اجرای کامپیوتر تو را به او نشان نمیدهد. برای آزمون کوتاه با چند نفر، ابزاری مانند ngrok میتواند دسترسی موقت به سرویس محلی بدهد؛ راهاندازی و ملاحظاتش را در مستندات ngrok ببین. لینک تونل را عمومی و بیحفاظ رها نکن، دادهٔ حساس آزمایشی وارد نکن و پس از آزمون دسترسی را ببند.
انتشار وب روی میزبانیای مانند Vercel مرحلهٔ متفاوتی است: خروجی باید برای محیط میزبانی ساخته و تنظیمات لازم آن بررسی شود. مستندات استقرار Vercel نقطهٔ شروع خوبی است، نه تضمین اینکه هر قالب KMP بدون تنظیم اضافه اجرا میشود. در لایو، نسخهٔ وب با لینک تونل در اختیار دیگران گذاشته شد و در پایان لینک Vercel نیز نمایش داده شد. نمایش این لینکها را با تأیید کارکرد کامل استقرار یا امنبودن و پایداری بازی برای همهٔ کاربران یکی نگیر.
در پایان، چیزی که تحویل میدهی فقط یک صفحهٔ چت نیست: پروژهٔ KMP با اجرای وب، docs/mafia-prd.md شامل قوانین و مرز نقشها، docs/mafia-checks.md شامل سناریوهای آزمون، و یک بازی کوتاه که در آن دستکم یک اتهام، یک رأی و گذار مرحله را خودت بررسی کردهای. یک بار هم از دید شهروند بررسی کن که اطلاعات نقشهای دیگر در ورودی شخصیت او نباشد. اگر این آزمون شکست خورد، پیش از افزودن تصویر، صدا یا لینک عمومی، همان مرز اطلاعاتی را درست کن.
ویدیوی کامل
اگر میخواهی روند کار و آزمونها را هم ببینی، ویدیوی کامل این آموزش اینجاست:


دیدگاهتان را بنویسید
برای نوشتن دیدگاه باید وارد بشوید.