Bloga Dön

Eksik Fortnite Creative 'Clear Player Data' Seçeneğini Çözme: Verse Sıfırlamaları ve Özel Backend Durum Kurtarma

Yayınlanma tarihi 19 Temmuz 2026
Eksik Fortnite Creative 'Clear Player Data' Seçeneğini Çözme: Verse Sıfırlamaları ve Özel Backend Durum Kurtarma

Özet olarak

Fortnite Creative ve UEFN yayınlama ekranlarında karşılaşılan eksik 'Clear Player Data' seçeneği sorunu, oyuncu persistence verilerinin yeni şemalarla uyumsuz kalmasına ve çökmelere yol açmaktadır. Bu sorunun önüne geçmek için Verse içinde özel bir sürüm kontrolü (schema versioning) mekanizması kurularak eski verilerin kod düzeyinde sıfırlanması sağlanabilir. Yerel test süreçlerinde persistence önbelleği devre dışı bırakılabilirken, uzun vadede daha esnek ve sınırsız bir yönetim için verilerin [horizOn](https://horizon.pm) gibi harici bir backend mimarisine taşınması önerilmektedir.

En yeni Fortnite Creative veya UEFN haritanız hazır. Ekonominizi refactor ettiniz, sınıf (class) sisteminizi yeniden tasarladınız ve gameplay loop'unuzu optimize ettiniz. Ancak yayınlama aşamasına geldiğinizde, motoru kilitleyen bir kabusla karşılaşıyorsunuz: Yayınlama onay ekranındaki "Press Triangle to Clear Player Data" seçeneği ortadan kaybolmuş. Kapana kısıldınız. Oyuncularınız haritanıza güncel olmayan persistence verileriyle yükleniyor; bu da anında stack overflow hatalarına, bozuk quest line'lara ve oyunu çökerten durum uyumsuzluklarına (state mismatches) yol açıyor.

Bu sorun, Epic'in geliştirici forumlarındaki içerik üreticilerinin başını ağrıtıyor; zira sıfırlama butonunun aniden ortadan kalkması, eski production durumlarını temizlemek için arayüz tabanlı hiçbir mekanizma bırakmıyor. Oyuncu persistence veri şemanız (schema) değiştiğinde, Epic'in backend'i eski serialize edilmiş verileri yeni yapılarınızla eşleştirmeye çalışır. Eğer kodunuz bu uyumsuz özellikleri düzgün bir şekilde (gracefully) ele alacak şekilde tasarlanmadıysa, geri dönen oyuncularınızın %100'ü için oyun durumunu (game state) tamamen bozarsınız (brick edersiniz).

Bu rehberde, bu bug için teknik geçici çözümlere (workarounds) derinlemesine dalacağız. Verse içinde nasıl sağlam bir schema versioning sistemi kuracağınızı, test durumlarını temizlemek için yerel UEFN ayarlarını nasıl yapılandıracağınızı gösterecek ve özel harici backend çözümlerinin sizi kapalı platform persistence sınırlarından nasıl kurtarabileceğini inceleyeceğiz.

Temel Neden: Şemalar Sürüm Yükseltmelerinde Neden Başarısız Olur?

Fortnite Creative ve Unreal Editor for Fortnite (UEFN) üzerinde persistent veriler, Epic'in veritabanı altyapısında weak_map yapıları kullanılarak saklanır. Bir weak_map, bir oyuncu instance'ını <persistable> belirleyicisiyle (specifier) işaretlenmiş özel bir sınıfa (class) bağlar. Geleneksel SQL veya belge (document) veritabanlarının aksine, Epic'in depolama katmanı siz bir güncelleme yayınladığınızda resmi bir migration pipeline'ı çalıştırmaz. Bunun yerine, oyuncunun bulut kaydındaki mevcut ikili payload ne ise onu doğrudan güncel Verse sınıf tanımına deserialize etmeye çalışır.

Bir değişkeni sildiğinizde, bir özelliği yeniden adlandırdığınızda veya bir tipi değiştirdiğinizde (örneğin bir alanı int yerine float yaptığınızda), deserializer bir uyumsuzlukla karşılaşır. Değişikliğin ciddiyetine bağlı olarak, bu şema sapması (schema divergence) üç hata modundan birine neden olur:

  • Sessiz Hatalar (Silent Failures): Runtime, değiştirilen özelliklere varsayılan değerler atar; bu da çökmeye yol açmadan ilerlemeyi sıfırlar.
  • Durum Bozulması (State Corruption): Uygulama geçersiz bellek durumlarını okur veya beklenmeyen veri yapılarıyla karşılaşır, bu da başka yerlerde mantık hatalarını (logic errors) tetikler.
  • Ciddi Runtime Çökmeleri (Severe Runtime Crashes): Harita yüklenemez veya Verse VM, persistent map'i açamadığı (unpack edemediği) için yürütmeyi durdurur.

Yayıncı konsolunun "Clear Player Data" butonu kaybolduğunda, verileri küresel olarak tamamen sıfırlama yeteneğinizi kaybedersiniz. Eğer bir geliştirici, kayıt verisi düzeninde (save data layout) temel değişiklikler yaparsa oyun bozulur.

Manuel Çözüm: Verse İçinde Schema Versioning

Epic yayınlama portalının verileri temizlemesine güvenemeyeceğiniz için yazılım düzeyinde bir fallback mekanizması uygulamalısınız. Strateji oldukça basittir: Doğrudan persistable sınıflarınıza bir sürüm takipçisi (version tracker) ekleyin. Oyuncunun kayıtlı sürümünü oturum başlangıcında aktif uygulama sürümüyle karşılaştırarak güncelliğini yitirmiş kayıtları tespit edebilir ve üzerlerine varsayılan değerleri yazabilirsiniz.

İşte sürüm kontrollü bir persistence katmanı kuran, production'a hazır bir Verse implementasyonu.

using { /Fortnite.com/Devices }
using { /Fortnite.com/Characters }
using { /Fortnite.com/Playspaces }
using { /Verse.org/Simulation }

# A simple persistable class representing our player save schema.
# Note: Classes tagged with <persistable> can only contain certain types like int, float, string, and maps.
player_save_data := class<persistable>:
    # The SchemaVersion tracks which generation of player data this struct belongs to.
    SchemaVersion : int = 0
    GoldCount : int = 0
    XP : int = 0
    HasCompletedTutorial : int = 0  # Using int as a boolean flag representation for older Verse constraints

# The persistence manager device handles loading, validating, and migrating player data.
persistence_manager_device := class(creative_device):

    # By updating this value in the Editor, we force a schema migration next time the game runs.
    @editable
    TargetSchemaVersion : int = 2

    # Map to store player data in memory
    var PlayerDataMap : weak_map(player, player_save_data) = map{}

    # Initialize the persistence logic for a joining player
    InitializePlayer(Player : player) : void =
        # Check if the player already has persistent data
        if (ExistingData := PlayerDataMap[Player]):
            # If the stored version is older than our target version, trigger a manual reset
            if (ExistingData.SchemaVersion < TargetSchemaVersion):
                Print("Data version mismatch. Local: {ExistingData.SchemaVersion}, Target: {TargetSchemaVersion}. Resetting player data.")
                ResetPlayerData(Player)
            else:
                Print("Loaded existing player data. Version: {ExistingData.SchemaVersion}")
        else:
            # If no data exists, initialize a new record with the current version
            Print("No player data found. Initializing new record.")
            ResetPlayerData(Player)

    # Re-initializes a player's record with default values at the current version
    ResetPlayerData(Player : player) : void =
        NewData := player_save_data:
            SchemaVersion := TargetSchemaVersion
            GoldCount := 0
            XP := 0
            HasCompletedTutorial := 0

        # Save the freshly initialized data block to the persistence map
        if (set PlayerDataMap[Player] = NewData):
            Print("Successfully saved fresh persistent data block.")

Sürüm Oluşturma Script'inin Analizi

Bu şablon, InitializePlayer metodu içindeki erken doğrulamaya (early validation) dayanır. Adım adım mantık şu şekilde işler:

  1. Giriş Kontrolü (The Entry Check): Bir oyuncu katıldığında, sistem mevcut bir player_save_data instance'ı için PlayerDataMap'i sorgular.
  2. Sürüm Değerlendirmesi (The Version Assessment): Eğer bir kayıt durumu (save state) mevcutsa, motor bunun SchemaVersion özelliğini kontrol eder.
  3. Migration Tetikleyici (The Migration Trigger): Eğer SchemaVersion, cihazın @editable özelliği olan TargetSchemaVersion değerinden düşükse, script ResetPlayerData(Player) fonksiyonunu çağırır.
  4. Durumun Üzerine Yazma (State Overwrite): ResetPlayerData, yeni TargetSchemaVersion değerine ayarlanmış yeni bir player_save_data instance'ı oluşturur ve map'i günceller.

UEFN içindeki cihaz yapılandırmanızda TargetSchemaVersion değerini manuel olarak artırarak, bir sonraki oturum başlangıcında tüm oyuncular için hedef veri temizliğini zorunlu kılarsınız ve böylece eksik Epic kullanıcı arayüzü butonunu önemsiz hale getirirsiniz.

Adım Adım Test Prosedürü

Bu migration script'ini oyun testi (playtest) döngünüz içinde güvenli bir şekilde doğrulamak için şu sıralı adımları izleyin:

  1. Özel persistence_manager_device cihazınızı UEFN seviye viewport'una sürükleyin.
  2. UEFN Details panelinde, başlangıçtaki TargetSchemaVersion değerini 1 olarak ayarlayın.
  3. Bir oyun oturumu başlatın, biraz skor veya altın toplayın ve ardından oyunu sonlandırın.
  4. Editöre geri döndüğünüzde, cihaz üzerindeki TargetSchemaVersion alanını 1'den 2'ye güncelleyin.
  5. Oturumu tekrar başlatın. Konsol günlüğü (console log) çıktısını gözlemleyin: 'Data version mismatch. Local: 1, Target: 2. Resetting player data.'
  6. Oyuncunuzun altınının ve ilerlemesinin Verse VM'i çökertmeden temiz bir şekilde sıfırlandığını doğrulayın.

Yerel Geliştirme Ayarları: İterasyon Sırasında Kayıt Dosyalarını Devre Dışı Bırakma

Runtime kod sürümü oluşturma (versioning), canlı sunuculardaki sorunları çözse de yerel oyun testleri sırasında istenmeyen bir zorluk yaratır. Geliştirme aşamasındaki bir özelliği her değiştirdiğinizde UEFN içinde sürüm numarasını manuel olarak yükseltmek yorucudur. Hata ayıklama (debugging) sürecinizi kolaylaştırmak için editör ayarlarınız aracılığıyla yerel persistence özelliğini tamamen devre dışı bırakabilirsiniz.

Yerel persistence özelliğini devre dışı bırakmak için şu adımları izleyin:

  1. UEFN'de, Outliner panelindeki Island Settings kısmına gidin.
  2. User Options - Game Rules alt bölümünü arayın.
  3. Enable Persistence seçeneğini bulun ve devre dışı bırakın.
  4. Multiplayer döngülerini yerel olarak test ediyorsanız, Editor Preferences penceresini açın, In-Game Play menüsüne gidin ve Clear Local Saved Data On Launch onay kutusunu bulun. Bunu işaretlemek, her simülasyonun boş bir önbellekle (cache) başlamasını sağlar.

Ancak yerel devre dışı bırakmalar production senaryolarını simüle etmez. Persistence önbelleğe alma (caching) devre dışı bırakıldığında test iterasyon hızları 45 saniyeden 5 saniyenin altına düşebilse de, canlıya geçmeden önce persistence etkinleştirilmiş şekilde en az bir tam staging döngüsü çalıştırmalısınız. Bağlantı engellerinin birikebileceği yer yer burasıdır. Yerel playtest kurulumları sürücü çakışmalarıyla ünlüdür ve geliştiricilerin UEFN oturum başlatma zaman aşımı sorunları sırasında Unreal Engine ağ sürücülerinin teşhis edilmesi sürecinde değerli zaman kaybetmelerine neden olur.

UEFN'in Yerleşik Persistence Sınırlamaları

Verse'in yerel (native) persistence katmanını kullanmak ciddi mimari kısıtlamaları beraberinde getirir. Bulut temizleme seçenekleri kusursuz çalışsa bile, geliştiriciler katı platform limitlerine tabidir:

  • Depolama Bütçeleri (Storage Budgets): Persistable veri blokları, oyuncu başına oturum başına 12KB ile sınırlandırılmıştır. Bu sınırın aşılması durumun (state) kaydedilmesini engeller.
  • Yalnızca İlkel Tipler (Primitive Types Only): <persistable> olarak işaretlenmemiş özel sınıfları serialize edemezsiniz ve oyun nesnelerine (örneğin creative_device veya dinamik aktörler) referans depolayamazsınız.
  • Harici Sorgulama Yok (No External Querying): Epic'in sistemi tamamen bir kapalı kutudur (black box). Oyuncu verilerini harici bir dashboard üzerinden sorgulayamaz, açıklar (exploits) için kullanıcı durumlarını denetleyemez veya veritabanlarını dinamik olarak migrate edemezsiniz.
  • Telemetri Darboğazları (Telemetry Bottlenecks): UEFN içinde karmaşık analitik dashboard'ları tasarlamak, dize uzunluğu (string length) sınırlarıyla ciddi şekilde kısıtlanır. Örneğin geliştiriciler, 32 karakterlik UEFN analitik cihazı etkinlik adı sınırını aşma konusunda sürekli kısıtlamalarla mücadele etmektedir.

Basit minioyunlar için bu sınırlar yönetilebilir düzeydedir. Ancak karmaşık persistent RPG'ler, live-ops nişancı oyunları veya platformlar arası oyunlar için yalnızca tescilli, kapalı devre persistence yapısına güvenmek ölçeklendirme yolunuzu tıkar.

Mimarın Alternatifi: horizOn ile Harici Veritabanı Durumları

Platforma özel kullanıcı arayüzü bug'ları veya tescilli veri boyutlarıyla sınırlı olmayan ölçeklenebilir bir oyun oluşturmak için geliştiriciler harici backend mimarilerine yöneliyor. Oyun durumlarını Verse'in yerel bellek eşlemelerinde (memory maps) saklamak yerine, UEFN projeniz Verse'teki http_client modülünü kullanarak harici bir veritabanıyla iletişim kurabilir.

Bu yaklaşım, oyuncu kaydetme döngüsü üzerinde size tam kontrol sağlar. Oyuncu persistence verilerini temizlemeniz gerektiğinde, Epic konsolunda eksik bir butonu aramak veya bir kod güncellemesi göndermek zorunda kalmazsınız. Oyuncu tablolarını temizlemek, taşımak (migrate etmek) veya yamalamak için basitçe bir yönetici veritabanı script'i çalıştırabilir veya backend kontrol panelinizdeki tek bir butona tıklayabilirsiniz.

Bunu kendiniz kurmak; load balancer'lar kurmayı, veritabanı sharding işlemini ve SSL sertifikası yönetimini gerektirir ve bu da rahatlıkla 4-6 haftalık bir iş demektir. horizOn ile bu backend hizmetleri önceden yapılandırılmış olarak gelir ve altyapınız yerine oyununuzu yayınlamanıza olanak tanır.

Oyuncu durumlarını horizOn üzerinden yönlendirerek, Verse kodunuz temiz REST uç noktaları (endpoints) aracılığıyla durumu okuyan ve yazan basit bir istemci haline gelir:

# Pseudocode showing HTTP-based state synchronization with [horizOn](https://horizon.pm)
sync_manager_device := class(creative_device):

    # Send player progress to [horizOn](https://horizon.pm) endpoint
    SavePlayerState(Player : player, SaveData : player_save_data) : void =
        # In a real environment, you construct a JSON payload and dispatch it
        # via the Verse http_client. This bypasses the 12KB local persistence limit.
        RequestURL := "https://api.horizon.pm/v1/players/{GetPlayerID(Player)}/state"
        Print("Dispatching persistent payload to [horizOn](https://horizon.pm) at: {RequestURL}")
        
        # This keeps the server-side payload lightweight (under 240 bytes) 
        # while securing long-term storage off the Fortnite engine.

Bu kurulum, oynanış döngünüzü (gameplay loop) platformun fiziksel backend bug'larından tamamen ayırır. Eğer bir yama (patch) yerel kayıt uyumluluğunuzu bozarsa, canlı oyun sunucusunda sıfır kesintiyle horizOn veritabanınızda hedefli bir schema migration tetikleyebilirsiniz. Küçük yapısal ayarlamalar yüzünden canlı sunucuları bozma riskinden kaçınmış olursunuz.

Oyun Durumu Persistence Yönetimi için En İyi Pratikler

İster yerel Verse haritalarına bağlı kalın, ister harici bir sunucu mimarisinden yararlanın; stabil bir persistence yaşam döngüsü sürdürmek multiplayer oyunlar için hayati önem taşır. Oyuncu durumlarını korumak için şu ilkelere bağlı kalın:

  1. Örtük Sürüm Oluşturmayı Erken Uygulayın (Implement Implicit Versioning Early): Başlangıçtaki kayıt verisi düzeninize her zaman bir SchemaVersion tam sayısı ekleyin. Şemanızı değiştirmeyi düşünmeseniz bile, ilk günden itibaren sürüm anahtarına sahip olmak gelecekteki olası felaket boyutundaki veri bozulmalarını önler.
  2. Durum Doğrulama Kurallarını Uygulayın (Enforce State Validation Rules): Yüklenen durumu okurken her özelliğin sınırlarını (ranges) doğrulayın. Eğer bir oyuncunun kayıtlı altın sayısı negatifse veya haritanızın yapısal sınırını aşıyorsa, ekonomi açıklarını (exploits) önlemek için o belirli özelliği sıfırlayın.
  3. Kayıt Sıklığını En Aza İndirin (Minimize Save Frequency): Buluta yazmak maliyetlidir. Her jeton toplandığında veritabanını güncellemek yerine yazma işlemlerinizi gruplandırın (batch). Kaydetme işlemlerini; maç tamamlama, oyuncunun seviye atlaması veya oyuncunun oturumdan ayrılması gibi önemli kilometre taşlarında tetikleyin.
  4. Temiz Fallback Yapıları Oluşturun (Construct Clean Fallback Structs): Başarısız bir okuma işleminin oyuncunun oyuna girmesini engellemesine asla izin vermeyin. Eğer persistence payload'u deserialize edilemezse, anında varsayılan bir durum yapısına (default state structure) geri dönün.
  5. Gameplay Kodunu Depolama Mantığından Ayırın (Decouple Gameplay Code from Storage Logic): Depolama sorgularınızı özel bir persistence manager cihazında izole edin. Silahlarınız, ilerleme (progression) ve UI cihazlarınız veri eşlemesine doğrudan çağrı yapmak yerine bu manager'ı sorgulamalıdır.

Sonraki Adımlar

Kritik durum migration işlemlerini yönetmek için Epic'in konsol arayüzüne güvenmek riskli bir tasarım şablonudur. 'Clear Player Data' seçeneği başarısız olduğunda, Verse içindeki runtime sürüm yönetimi (versioning) ilk savunma hattınız olarak hizmet eder. Ancak oyununuz yüksek sıklıkta kayıt, karmaşık telemetri veya tam yönetimsel kontrol gerektiriyorsa, veritabanınızı özel bir backend'e taşımak nihai çözümdür.

Multiplayer backend'inizi ölçeklendirmeye hazır mısınız? horizOn'u ücretsiz deneyin veya API dökümanlarına göz atın.


Kaynak: clear players data button in creative 1