10 Ekim 2026 Cumartesi

Mobil Oyunlarda Google Play Games Nailiyyətlər (Achievements) Sistemi: Mağaza Təsiri, 2.000 XP Limiti və MonoGame Memarlığı




Mobil Oyunlarda Google Play Games Nailiyyətlər (Achievements) Sistemi: Mağaza Təsiri, 2.000 XP Limiti və MonoGame Memarlığı

Bir mobil oyunu hazırlayıb mağazada yayımladıqdan sonra əsl sınaq başlayır: oyunçunun ilk bir neçə dəqiqəlik marağını uzunmüddətli bağlılığa çevirmək. Oyunçular sadəcə "mərhələni keç, növbətiyə başla" dövrəsi ilə baş-başa qaldıqda, bir müddət sonra yorğunluq yaranır və ya qurduğunuz dərin oyun mexanikalarının yarısını belə kəşf etmədən tətbiqi bağlayırlar.

İlk baxışda Google Play Games Services (GPGS) Nailiyyətlər (Achievements) sistemi sadəcə kiçik nişanlar toplusu kimi görünə bilər. Lakin düşünülmüş şəkildə dizayn edildikdə, o, oyunçuları oyununuzun mexanikasının hər bir qatına yönləndirən güclü bir saxlama (retention) mühərrikinə çevrilir.

Bu texniki məqalədə nailiyyətlərin Google Play ekosistemində real olaraq nə qazandırdığını, Blocked: Pixel Panzer üçün Google-un sərt XP qaydaları çərçivəsində 79 fərqli nailiyyəti necə dizayn etdiyimizi və gərgin arkada döyüşləri zamanı FPS düşüşlərinin və Android ANR (Application Not Responding) xətalarının qarşısını alan asinxron MonoGame / C# batching mexanizmini necə qurduğumuzu təhlil edirik.


1. Google Play Games Nailiyyətləri Niyə Əhəmiyyətlidir?

Google Play Games nailiyyətlərini inteqrasiya etmək həm oyunçu psixologiyası, həm də mağaza performans göstəriciləri üzrə dörd konkret fayda təmin edir:

  1. Alternativ Hədəflər və Oyunçu Bağlılığı (Day-7 / Day-30 Retention):
    Hər bir oyunçu qlobal liderlər cədvəlində (leaderboard) 1-ci yeri tuta bilməz, lakin hər kəs "100 Qüllə Məhv Et" və ya "Heç bir zərər almadan mərhələni tamamla" hədəfinə doğru irəliləyə bilər. Pilləli (incremental) nailiyyətlər hər oyun sessiyasında irəliləyən real bir tərəqqi paneli təqdim edir.
  2. Oyun Mexanikalarını Təbii Yolla Öyrətmək (Gizli Onboarding):
    Oyunçular çox vaxt standart silahlarından istifadə edir və yeni üsulları sınamaqdan çəkinirlər. Blocked: Pixel Panzer-də ColorWheel üzərində yaşıl turşu gülləsi ilə blokları eyni vaxtda əritməyə və ya qara güllə ilə kritik zərbələr endirməyə görə nailiyyət vermək, onları hər bir elementar rejimi kəşf etməyə və mənimsəməyə təşviq edir.
  3. Anlıq Əks-Əlaqə və Google Play Oyunçu XP-si:
    Qızğın döyüşün ortasında rəsmi Google Play Games bildirişinin ekranın yuxarısından enməsini görmək və qlobal Google Play Oyunçu Səviyyəsi üçün XP qazanmaq oyunçulara əməliyyat sistemi profili ilə əlaqəli qalıcı bir irəliləyiş hissi verir.
  4. Google Play Ekosistemi və Keyfiyyət Siqnalları:
    Google Play Games Services V2 (PGS V2) inteqrasiyası Zero-Tap avtomatik daxilolma, Google Play Games on PC ilə tam uyğunluq və Google Play Store-un "Oyunlar" bölməsində daha güclü cəlbetmə siqnalları qazandırır.

Blocked: Pixel Panzer Oyun İçi Nailiyyət Bildirişi
Blocked: Pixel Panzer oyununda 103-cü Səviyyə döyüşü zamanı 10-cu qüllə məhv edildiyi anda ekranın yuxarısında görünən rəsmi Google Play Games "Turret Buster I" bildirişi.


2. Google Play Console Qaydaları: 2.000 XP Limiti və 10.000 Addım Qaydası

Google Play Console-da nailiyyətləri tənzimləyərkən üç sərt platforma məhdudiyyətini nəzərə almalısınız:

  • 2.000 XP Sərt Limiti (Hard Cap): Tək bir oyunda bütün nailiyyət xallarının cəmi 2.000 XP-dən çox ola bilməz. Hər bir fərdi nailiyyət 5 ilə 200 XP arasında olmalı və 5-in qatları şəklində verilməlidir.
  • Pilləli Nailiyyətlər üçün 10.000 Addım Limiti: Kumulyativ sayğaclı nailiyyətlər Play Console-da maksimum 10.000 addımı (steps) dəstəkləyir.
  • Play Games Services V2 Tələbi: Google köhnə V1 SDK-nı ləğv edir. Müasir Android oyunları Xamarin.GooglePlayServices.Games.V2 (PlayGamesSdk və PlayGames.GetAchievementsClient) üzərində qurulmalıdır.

Blocked: Pixel Panzer-də 79 Nailiyyətlik Kataloq Dizaynı

Əsas oyun obyektlərimizi (TurretBlock, FighterJet, EnemyRocket, ColorWheel, HydraRegenerationSkill, Season) təhlil edərək, 6 əsas kateqoriya üzrə cəmi 1.995 / 2.000 XP dəyərində 79 nailiyyət formalaşdırdıq:

Kateqoriya Nümunə Nailiyyətlər Növ Hədəf / Mexanika
Düşmən Ovçuları Jet Hunter I–III, Sky Dominator, Turret Buster I–III, Siege Master Pilləli 10, 100, 1.000 və 10.000 qırıcı təyyarə, müdafiə qülləsi və idarəolunan raket məhv etmək.
Blok Dağıdılması və Partlayıcılar Pioneer Breaker, Demolition Crew, Crusher Supreme, Pixel Obliterator, Chain Reaction Pilləli / Standart 1.000-dən 10.000-ə qədər blok qırmaq və tək dinamit partlayışı ilə 5/25/50 hədəfi partlatmaq.
ColorWheel və Silah Ustalığı Prismatic Pilot, Acid Dissolver, Critical Striker, Power Blaster, Speedy Sprinter, Beam Vaporizer Pilləli Yaşıl turşu gülləsi ilə blokları əritmək, qara kritik vuruşlar etmək, qırmızı güc atışları, lazerlər və idarəolunan raketlər.
Mərhələ və Boss İrəliləyişi First Blood, Giant Slayer, Decimator, Speedrunner I–III Pilləli / Standart İlk düşmən məhvi, ilk Boss qələbəsi və mərhələləri 4 dəqiqədən az müddətdə tamamlamaq.
Purist (Bacarıqsız / Xəsarətsiz) Sınaqlar Untouchable, Clean Victory I–III, Purist Gladiator, Mono Specialist Pilləli / Standart Heç bir zərər almadan və ya heç bir bacarıq (skill) istifadə etmədən Bossları məğlub etmək və yüksək səviyyəli mərhələləri keçmək.
Atmosfer, Təchizat və Meta Storm Fighter, Retro Connoisseur, Gem Tycoon, Quad Spectrum, Audiophile, Loyal Supporter Pilləli / Gizli Yağışlı havada 100 qüllə dağıtmaq, CRT monitorları toplamaq və musiqi pleyerində tam treklərə qulaq asmaq.

Hər bir nailiyyət üçün çətinlik artdıqca çərçivələri bürüncdən qızıla və prizmatik pillələrə yüksələn xüsusi 512x512 piksel-art nişan ikonları hazırladıq:

Blocked: Pixel Panzer Xüsusi Nailiyyət Nişanları
79 nailiyyətlik kataloqumuzdan 6 nümunə 512x512 nişan: Sky Dominator, Turret Buster III, Pixel Obliterator, Prismatic Pilot IV, Acid Dissolver II və Power Blaster II.

Peşəkar Məsləhət (Toplu ZIP İdxalı): 79 nailiyyəti Google Play Console veb interfeysində əllə tək-tək daxil etmək saatlarla vaxt aparır. Əvəzində AchievementsMetadata.csv, AchievementsIconsMappings.csv və 512x512 .jpg ikonlarınızı tək bir .zip arxivində birləşdirərək Play Console-un "Import achievements" funksiyasından istifadə edin və bütün kataloqu saniyələr ərzində idxal edin.

Google Play Console Yayımlanmış Nailiyyətlər Cədvəli
Google Play Console daxilində yayımlanmış nailiyyətlərimiz və XP paylanması cədvəli.


3. Təmiz Arxitektura: Ortaq Kodda IGamesService və AchievementDirector

Blocked: Pixel Panzer həm Windows PC (Microsoft Store), həm də Android (Google Play) üzərində işləyən kross-platformalı MonoGame layihəsidir. Ortaq oyun layihəmizi (Blocked.Shared) Android SDK asılılıqlarından tamamilə azad saxlamaq üçün Asılılığın İnversiyası Prinsipini (Dependency Inversion Principle - SOLID) tətbiq edirik.

Əvvəlcə ortaq təbəqədə platformadan asılı olmayan IGamesService interfeysini təyin edirik:

namespace Blocked.Shared.Services
{
    public interface IGamesService
    {
        void Initialize();
        Task<bool> SignIn();
        Task<bool> IsAuthenticated();
        
        // Leaderboards
        void SubmitScore(string leaderboardId, long score);
        void ShowLeaderboards();
        void ShowLeaderboard(string leaderboardId);

        // Achievements
        void UnlockAchievement(string achievementId);
        void IncrementAchievement(string achievementId, int steps = 1);
        void ShowAchievements();
    }
}

Nailiyyət yoxlamalarını CollisionManager, GameplayScreen və Player daxilində səpələmək əvəzinə, bütün 79 qaydanı AchievementDirector adlı vahid əlaqələndirici sinifdə mərkəzləşdiririk:

public static class AchievementDirector
{
    public static void OnEnemyKilled(
        bool isJet = false,
        bool isTurret = false,
        bool isRocket = false,
        bool isBoss = false,
        Bullet? killingBullet = null,
        bool killedByLaser = false)
    {
        var gamesService = ScreenManager.Instance?.GamesService;
        if (gamesService == null) return; // Safely no-ops on Desktop PC builds

        if (isTurret)
        {
            gamesService.IncrementAchievement(AchievementIds.TurretBuster1, 1);
            gamesService.IncrementAchievement(AchievementIds.TurretBuster2, 1);
            gamesService.IncrementAchievement(AchievementIds.TurretBuster3, 1);
            gamesService.IncrementAchievement(AchievementIds.SiegeMaster, 1);

            // Turrets destroyed during rainy weather advance "Storm Fighter"
            if (Season.Current == SeasonKind.Rainy)
            {
                gamesService.IncrementAchievement(AchievementIds.StormFighter, 1);
            }
        }

        TrackWeaponKill(gamesService, killingBullet, killedByLaser);
    }
}

4. Kritik Mühəndislik: ANR-lərin Qarşısını Almaq Üçün JNI / Binder IPC Yükünün Aradan Qaldırılması

Sürətli templi arkada oyununda nailiyyət tətikləyicilərini birbaşa Google Play SDK-ya bağlamaq ciddi performans tələsi yaradır:

Oyunçu Partlayıcı Bloku (ExplosiveBlock) partlatdıqda və ya Laser Beam bacarığından istifadə etdikdə, tək bir kadrda (16.6 millisaniyə) 20-30 blok və düşmən məhv edilə bilər. Hər bir məhvetmə 5 və ya 6 pilləli səviyyəni yenilədikdə, tək bir kadr 150-dən çox IncrementAchievement çağırışını işə sala bilər!

Əgər əsas oyun dövrəsi axınında (thread) Google Play Services-ə 150 sinxron JNI və Binder IPC çağırışı göndərsəniz:

  1. Başlanğıc səviyyəli Android cihazları (1–2 GB RAM-a malik Android Go telefonları) dərhal ciddi kadr donmalarından əziyyət çəkir.
  2. JNI Qlobal İstinad (GREF) cədvəli şişir və Google Play Vitals-da ANR (Input dispatching timed out) hesabatlarına səbəb olur.

Bizim Həllimiz: Yaddaşda 1.5 Saniyəlik Qruplaşdırma (Batching) və Sessiya Təkrarlanmasının Qarşısının Alınması

GooglePlayGamesService.cs daxilindəki tətbiqimiz MonoGame yeniləmə dövrəsini Google Play IPC çağırışlarından tamamilə təcrid edir:

  1. Sessiya Təkrarlanmasının Qarşısının Alınması (_unlockedInSession):
    Standart nailiyyət bir sessiya ərzində açıldıqdan sonra onun ID-si HashSet<string>-ə əlavə edilir. Eyni və ya sonrakı kadrlarda təkrarlanan tətiklənmələr sıfır JNI xərci ilə birbaşa C#-da geri qayıdır.
  2. 1.5 Saniyəlik Arxa Plan Qruplaşdırması (_pendingIncrements):
    IncrementAchievement çağırışı sadəcə əsas axında yaddaşdakı Dictionary<string, int> daxilində tam ədədi artırır (sıfır JNI çağırışı). Arxa plan Task.Run işçisi 1.5 saniyədən sonra oyanır, toplanmış cəmlərin anlıq görüntüsünü (snapshot) alır və onları Google Play Services-ə hər nailiyyət üçün vahid birləşdirilmiş çağırışla göndərir.
  3. 26502: CLIENT_RECONNECT_REQUIRED İdarə Edilməsi və Oflayn Keşləmə:
    Oyunçu oyunu saatlarla arxa plana atıb geri qayıtdıqda, Google Play sessiya tokeninin vaxtı bitə bilər və 26502 (CLIENT_RECONNECT_REQUIRED) xətası verə bilər. Xidmətimiz bunu tutur, cooldown mühafizəsi ilə tək bir səssiz arxa plan SignIn() cəhdi edir və cihaz oflayndırsa, GPGS-in lokal oflayn keşinə (client.Unlock) müraciət edir—bu da oyunçunun heç bir nailiyyətinin itirilməməsini təmin edir.
private static readonly HashSet<string> _unlockedInSession = new(StringComparer.Ordinal);
private static readonly Dictionary<string, int> _pendingIncrements = new(StringComparer.Ordinal);
private static readonly object _achievementBatchLock = new();
private static bool _incrementFlushScheduled = false;

public void IncrementAchievement(string achievementId, int steps = 1)
{
    if (!_isInitialized || string.IsNullOrEmpty(achievementId) || steps <= 0)
        return;

    bool shouldSchedule = false;
    lock (_achievementBatchLock)
    {
        // ZERO JNI cost on the game loop thread — pure in-memory aggregation!
        if (_pendingIncrements.TryGetValue(achievementId, out int current))
            _pendingIncrements[achievementId] = current + steps;
        else
            _pendingIncrements[achievementId] = steps;

        if (!_incrementFlushScheduled)
        {
            _incrementFlushScheduled = true;
            shouldSchedule = true;
        }
    }

    if (shouldSchedule)
    {
        Task.Run(async () =>
        {
            await Task.Delay(1500).ConfigureAwait(false);
            FlushPendingIncrementsNow();
        });
    }
}

private void FlushPendingIncrementsNow()
{
    List<KeyValuePair<string, int>>? snapshot = null;

    lock (_achievementBatchLock)
    {
        _incrementFlushScheduled = false;
        if (_pendingIncrements.Count == 0) return;

        snapshot = new List<KeyValuePair<string, int>>(_pendingIncrements);
        _pendingIncrements.Clear();
    }

    var act = _activity;
    if (act == null || act.IsFinishing || act.IsDestroyed) return;

    var client = PlayGames.GetAchievementsClient(act);
    foreach (var kvp in snapshot)
    {
        if (kvp.Value > 0)
        {
            // 150 frame events become 1 combined step call to GPGS
            client.Increment(kvp.Key, kvp.Value);
        }
    }
}

5. Oyunçular Öz Nailiyyətlərini Oyun Daxilində Necə İzləyirlər?

Döyüş zamanı açılan bildirişlər əladır, lakin oyunçuların kilidli nişanlara baxmaq, pilləli səviyyələrdə faiz tərəqqisini yoxlamaq və növbəti hədəflərini seçmək üçün aydın bir məkana da ehtiyacı var.

Bunu səliqəli şəkildə dəstəkləmək üçün mobil statistika ekranımızı vahid STATS & RANKS mərkəzinə çevirdik. Ekranın yuxarısında iki qızılı düymə—LEADERBOARD və ACHIEVEMENTS—2 saniyəlik hamar sinus dalğası parıltısı ilə (Math.Sin) döyünür. Windows Desktop versiyalarında bu mobil düymələr avtomatik olaraq gizlənir və klassik STATISTICS tərtibatının təmizliyini qoruyur.

Oyunçu ACHIEVEMENTS düyməsinə toxunduqda:

  1. İnterfeys açılmazdan əvvəl son 1.5 saniyəlik hər hansı tərəqqinin qeydə alınması üçün FlushPendingIncrementsNow() dərhal icra edilir.
  2. GetAchievementsIntent() birbaşa oyunun üzərində Google Play Games-in yerli Achievements pəncərəsini açır:

Google Play Games Yerli Nailiyyətlər Pəncərəsi Blocked: Pixel Panzer-də
STATS & RANKS ekranından açılmış Google Play Games yerli nailiyyətlər pəncərəsi; ümumi tamamlanmanı (2 / 79), tövsiyə olunan hədəfləri, kilidi açılmış nişanları (Loyal Supporter, Audiophile) və kilidli pilləli halqaları göstərir.

Oyunçular tətbiqdən çıxmadan öz 2 / 79 tərəqqisini yoxlaya, fərdiləşdirilmiş tövsiyələrə baxa və pilləli faiz halqalarını izləyə bilərlər.


6. Nəticə və Oyunlarımız

Balanslaşdırılmış 2.000 XP büdcəsi və bloklamayan arxa plan batching boru kəməri ilə qurulduqda, Google Play Games Nailiyyətləri kadr sürətini qurban vermədən arkada oyununa dərinlik və uzunmüddətli təkrar oynanıla bilənlik əlavə etməyin ən təsirli yollarından biridir.

Əgər 79 nailiyyətlik irəliləyiş sistemimizi, ColorWheel döyüş mexanikasını və qlobal liderlər cədvəlini şəxsən təcrübədən keçirmək və ya digər oyunlarımızla tanış olmaq istəyirsinizsə, onları aşağıdakı mağazalarda tapa bilərsiniz:

🎮 Oyunlarımız:

📢 Devloqlarımızı və İcmamızı İzləyin:

Daha çox texniki məqalə, pərdəarxası görüntülər və oyun yeniləmələri üçün bizi izləyin:


Tags & Topics

#GooglePlayGames #Achievements #MonoGame #CSharp #MobileGameDev #AndroidDev #IndieDev #GameArchitecture #BlockedPixelPanzer #PaintTrek #ArarGames




Hiç yorum yok:

Yorum Gönder