مسئلهای که باید حل میکردم
مسابقهای که بازیکن پنج دقیقه از برنامه بیرون رفته، پنج دقیقه بازی بیشتر نکرده هست. من زمان فعالیت را از زمان دیواری برای گزارش مسابقه جدا کردم.
پیادهسازی در نسخهٔ فعلی
ForegroundMatchClock یک تابع now میگیرد. Seconds زمان جمعشده و بخش فعال را حساب میکنه؛ Pause آن را freeze میکنه و Resume مبدا بازهٔ فعال تازه میسازد.
تصمیم و هزینهٔ طراحی
تزریق تابع زمان اجازه میدهد منطق ساعت بدون وابستگی مستقیم به MonoBehaviour توضیح داده بشه. Pause و Resume تکراری اثر اضافه نمیگذارند و مقدار منفی clamp میشود.
مرزهای فعلی
درستی این ساعت به ساعت یکنواخت و فراخوانی درست چرخهٔ توقف بستگی داره. کد بهتنهایی نمیفهمد اپ به پسزمینه رفته و ذخیرهٔ دوام بین اجرای فرایند هم نیست.
سناریوهای بررسی و معنای قرارداد
برای نمونه، مسابقهای با چند دقیقه بازی و چند دقیقه خروج از برنامه دو مدت متفاوت داره. ساعت foreground تنها بازههای فعال را جمع میکنه و اختلاف زمان شروع و پایان دیواری لزوماً همان عدد نیست. این مثال عدد گزارش واقعی نیست و فقط تعریف معیار را روشن میکنه. Pause و Resume بدون اثر تکراری کمک میکنند چند callback مشابه زمان را دوباره جمع نکند. اما اتصال صحیح به چرخهٔ عمر برنامه همچنان شرط هست؛ خود این کلاس نمیداند پنجره واقعاً در پیشزمینه بوده یا نه. انتخاب تابع زمان نیز باید با انتظار یکنواخت بودن آن سازگار باشد.
در موتور گزارش PHP، checkpointهای game_progress و رویداد game_end میتوانند برای مدت همان match با Latest record per entity خوانده بشن. کلید انتخاب آخرین رکورد از player_id و شناسهٔ match ساخته میشود تا شناسهٔ مشابه دو بازیکن با هم ادغام نشود. ابتدا انتخاب رویداد و فیلتر انجام میشود و بعد آخرین رکورد بر اساس زمان انتخاب میشود. بازهٔ تاریخ نیز بر زمان رویداد در UTC استوار هست، نه روز شروع مسابقه. بنابراین مسابقهای که پایانش روز بعد هست خودکار به گروه همهٔ شروعهای روز قبل وصل نمیشود. checkpoint بدون پایان فقط زمان گزارششده را نشان میدهد و باقیماندهٔ بازی حدس زده نمیشود؛ این مرز برای خواندن صادقانهٔ مدت اهمیت داره.
آخرین checkpoint و پایان نهایی همیشه یک معنا ندارند. اگر بازی قطع بشه، گزارش میتواند تنها شاهد ناقص زمان فعال را داشته باشد. من این مشاهده را به عنوان حد گزارششده میخوانم و پایان یا برد را از نبودن رویداد حدس نمیزنم. جدا نگه داشتن دلیل پایان، زمان فعال و وجود رویداد نهایی اجازه میدهد تحلیل، دادهٔ ناقص را با تجربهٔ کوتاه موفق مخلوط نکند.
چیزی که از این مرحله یاد گرفتم
برای من، تعریف زمان بخشی از تعریف متریک شد. مدت foreground میتواند رفتار بازی را بهتر از فاصلهٔ دو timestamp توضیح بدهد، ولی باید کنار علت پایان و وضعیت نشست خوانده بشه.
سورس و گفتگو دربارهٔ پروژه: GitHub · Telegram
مثال عملی زمان مسابقه
یک روش کاربردی برای بررسی زمان مسابقه این است که به جای چند تغییر همزمان، تنها یک مسیر کوتاه بسازی. مسابقه با مکث، رفتن برنامه به پسزمینه و برگشت بازیکن ادامه پیدا میکند. سپس وضعیت قبل و بعد را کنار هم قرار بده. چه بخشی از داده تغییر کرده و کدام بخش فقط ظاهر تازهای پیدا کرده است؟ پاسخ باید از همان تعریف موضوع بیاید. این موقعیت یک مثال آموزشی است و آمار واقعی محصول یا وعدهٔ قابلیت جدید محسوب نمیشود.
خطای رایج و علت آن
زمان دیواری ممکن است زمان انتظار و توقف را هم به عنوان بازی فعال حساب کند. این خطا معمولاً وقتی پنهان میماند که فقط مسیر موفق و ظاهر نهایی را ببینیم. برای پیدا کردن علت، آخرین وضعیت درست را از نخستین وضعیت نادرست جدا کن و ببین تغییر دقیقاً در کدام مرز رخ داده است. مدت فعال بازی و زمان سپریشده دو معیار متفاوت با کاربرد متفاوتاند. اگر این تفاوت در قرارداد مشخص نباشد، اصلاح یک نشانه ممکن است همان مسئله را در بخش دیگری دوباره ایجاد کند.
چطور نتیجه را بررسی کنیم؟
زمان آغاز، پایان و سیاست توقف را در گزارش مدت توضیح بده. اجرای یکباره برای نتیجهگیری کافی نیست؛ یک بار مسیر معمول و بار دیگر همان موقعیت را با ورودی مرزی یا تکرار اقدام بررسی کن. اگر نتیجه فرق دارد، ورودی و شرایط اجرا را همراه خروجی نگه دار تا مقایسه قابل بازسازی باشد. جدول زیر خلاصهٔ مشخصات همین سناریو است و برای ثبت نتیجهٔ بررسی به کار میآید.
| بخش بررسی | آنچه باید ثبت شود |
|---|---|
| موقعیت آزمایشی | مسابقه با مکث، رفتن برنامه به پسزمینه و برگشت بازیکن ادامه پیدا میکند. |
| ریسک اصلی | زمان دیواری ممکن است زمان انتظار و توقف را هم به عنوان بازی فعال حساب کند. |
| روش بررسی | زمان آغاز، پایان و سیاست توقف را در گزارش مدت توضیح بده. |
| مرز نتیجهگیری | مدت فعال بازی و زمان سپریشده دو معیار متفاوت با کاربرد متفاوتاند. |
پرسشهای کاربردی دربارهٔ زمان مسابقه
از کجا شروع کنم؟
از همان موقعیت محدود این مطلب شروع کن: مسابقه با مکث، رفتن برنامه به پسزمینه و برگشت بازیکن ادامه پیدا میکند. ابتدا نتیجهٔ مورد انتظار را مشخص کن و بعد سراغ پیادهسازی یا ابزار برو. وقتی مسیر پایه قابل توضیح و بررسی شد، میتوان حالتهای بیشتری اضافه کرد. ساخت همهٔ حالتها از ابتدا، فهم علت خطا را سختتر میکند.
چه زمانی میتوانم بگویم این بخش درست کار میکند؟
زمانی که رفتار در موقعیت تعریفشده با قرارداد سازگار باشد و محدودیتهای آن روشن بمانند. زمان آغاز، پایان و سیاست توقف را در گزارش مدت توضیح بده. موفقیت در این آزمون دربارهٔ همان سناریو شاهد میدهد؛ از آن نمیتوان بدون بررسی دربارهٔ همهٔ دستگاهها، همهٔ قوانین محلی یا همهٔ حجمهای داده نتیجه گرفت. مدت فعال بازی و زمان سپریشده دو معیار متفاوت با کاربرد متفاوتاند.
برای ادامهٔ همین موضوع، آنالیتیکس چیست؟ از شمارش رویداد تا فهم مسیر بازیکن و Bunny Circus Analytics را ببین. زمینهٔ ساخت این پروژهها و معرفی سازنده در صفحهٔ کیان پاک نعمت آمده است.




