Windows Uygulama Paketleme etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster
Windows Uygulama Paketleme etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster

20 Eylül 2026 Pazar

MonoGame Masaüstü Oyunlarını Microsoft Store'da Yayınlama: Eksiksiz MSIX ve WAP Rehberi

MonoGame Masaüstü Oyunlarını Microsoft Store'da Yayınlama: Eksiksiz MSIX ve WAP Rehberi

Bağımsız bir oyunu Windows 10 ve Windows 11'deki Microsoft Store platformuna taşımak; geliştiricilere yüz milyonlarca PC oyuncusuna doğrudan erişim, arka planda otomatik güncellemeler, Windows Game Bar entegrasyonu ve güvenli yalıtılmış kurulum imkanı sağlar. Ancak oyununuz MonoGame (.NET 8.0 veya .NET 9.0 WindowsDX) ile geliştirilmişse, oyunu mağazaya sokmak özel bir mimari köprü gerektirir: standart bir Win32 masaüstü çalıştırılabilir dosyasını (.exe) modern MSIX / AppX uygulama modeline bağlamak.

Arar Games olarak Paint Trek ve Blocked: Pixel Panzer yapımlarımızla ilk derlemeden canlı mağaza dağıtımına kadar bu sürecin tüm aşamalarını bizzat deneyimledik. Bu rehberde; proje yapılandırmasından Visual Studio Publish seçeneklerine, Package.appxmanifest ayarlarından görsel kutucuk (tile) ölçeklemelerine, Windows Uygulama Sertifikasyon Kiti (WACK) doğrulamasından Microsoft Partner Center gönderimine kadar uçtan uca tüm teknik adımları ele alıyoruz.


1. Mimari Temel: Win32 ve MSIX Karşılaştırması

Geleneksel MonoGame oyunları; standart bir Win32 çalıştırılabilir dosyası (.exe), çalışma zamanı kütüphaneleri (.dll) ve derlenmiş ikili varlıkları içeren bir Content/ klasörü (.xnb dokuları, .ogg sesleri, sprite atlasları ve HLSL gölgelendiricileri) şeklinde derlenir.

Microsoft Store artık paketlenmemiş ham Win32 çalıştırılabilir dosyalarını da desteklese de, oyununuzu bir Windows Uygulama Paketleme (WAP) projesiyle sarmalayarak bir MSIX paketi (bundle) oluşturmak çok önemli avantajlar sunar:

flowchart TD
    subgraph "Oyun Kod Tabanı"
        Shared["Ortak Kütüphane (Shared)\n(Varlıklar, Sistemler, Oyun Durumu, Matematik)"]
        Desktop["Masaüstü Projesi (.NET 9.0 WindowsDX)\n(Win32 Executable Giriş Noktası)"]
        Shared --> Desktop
    end

    subgraph "Paketleme Katmanı (WAP Projesi)"
        WAP["Windows Uygulama Paketleme (.wapproj)\n(Microsoft Desktop Bridge)"]
        Manifest["Package.appxmanifest\n(Kimlik, İzinler, Görsel Varlıklar)"]
        StoreAssoc["Package.StoreAssociation.xml\n(Partner Center Eşleştirmesi)"]
        Desktop --> WAP
        Manifest --> WAP
        StoreAssoc --> WAP
    end

    subgraph "Çıktı ve Dağıtım"
        WAP -->|Create App Packages| Sideload["Sideloading Paketi\n(*.appxbundle + Add-AppDevPackage.ps1)"]
        WAP -->|Store Upload Modu| UploadBundle["Mağaza Yükleme Paketi\n(*_bundle.appxupload / *.msixupload)"]
        UploadBundle --> MSStore["Microsoft Partner Center\n(Canlı Mağaza Yayını)"]
    end

Neden MonoGame Projesini WAP ile Sarmalamalıyız?

  1. Yalıtılmış Konteyner Yaşam Döngüsü: MSIX uygulamaları izole bir sanal ortamda çalışır. Uygulama kaldırıldığında tüm dosyalar ve sanallaştırılmış kayıt defteri girdileri sistemde hiçbir çöp bırakmadan temizlenir.
  2. Dinamik Mimari ve Varlık Dağıtımı: Tek bir .appxupload paketi hem x86 hem de x64 ikililerini ve farklı ekran DPI ölçeklerini (scale-100 ile scale-400 arası) bir arada barındırır. Mağaza, kullanıcının bilgisayarına yalnızca gereken mimariyi ve ekran varlıklarını indirerek dosya boyutunu düşürür.
  3. Otomatik Çökme Analitiği: Visual Studio, genel hata ayıklama sembollerini (.appxsym) otomatik olarak yükleme arşivine ekler. Oyun bir oyuncunun cihazında çöktüğünde, Partner Center kontrol panelinde fonksiyon adları ve satır numaralarıyla tam çağrı yığınını (stack trace) görebilirsiniz.

2. Proje Hiyerarşisi ve Yapılandırması

Temiz bir MonoGame çözümü, oyun mantığı ile platform paketlemesini birbirinden ayırmalıdır:

SolutionDir/
│
├── YourGame.Shared/               # Çekirdek mekanikler, sistemler, seviyeler (Shared Library)
│   └── YourGame.Shared.csproj
│
├── YourGame.Desktop/              # Masaüstü giriş noktası (WinExe)
│   ├── Content/                   # MonoGame Content Pipeline varlıkları (.mgcb -> .xnb)
│   ├── Program.cs
│   └── YourGame.Desktop.csproj
│
└── YourGame.Package/              # Windows Uygulama Paketleme Projesi (.wapproj)
    ├── Images/                    # Ölçekli logolar, kutucuklar, açılış ekranı
    ├── Package.appxmanifest       # Kimlik, izinler, görsel öğeler
    ├── Package.StoreAssociation.xml
    └── YourGame.Package.wapproj

Adım 1: Ana Oyun Projesinin Yapılandırılması (.csproj)

Masaüstü projenizin çoklu mimari derlemeyi desteklediğinden emin olun:

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <OutputType>WinExe</OutputType>
    <TargetFramework>net9.0-windows</TargetFramework>
    <UseWindowsForms>true</UseWindowsForms>
    <ApplicationHighDpiMode>PerMonitorV2</ApplicationHighDpiMode>
    <Platforms>AnyCPU;x64;x86</Platforms>
  </PropertyGroup>

  <!-- Paketleme sırasında oyun içeriğinin kopyalanmasını garantiye alın -->
  <ItemGroup>
    <Content Include="Content\**\*.*">
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
    </Content>
  </ItemGroup>

  <ItemGroup>
    <PackageReference Include="MonoGame.Framework.WindowsDX" Version="3.8.*" />
    <PackageReference Include="MonoGame.Content.Builder.Task" Version="3.8.*" />
  </ItemGroup>
</Project>

Adım 2: Çoklu Platform NuGet Paketlerini Geri Yükleme

Paketleme öncesinde paketleri 64-bit ve 32-bit çalışma zamanları için açıkça geri yükleyin:

dotnet restore YourGame.Desktop.csproj -r win-x64
dotnet restore YourGame.Desktop.csproj -r win-x86

3. Visual Studio Publish Menüsü Seçenekleri

Visual Studio'da Windows Uygulama Paketleme projesine sağ tıklayıp Publish alt menüsünü açtığınızda üç ana seçenek görürsünüz:

graph TD
    Menu["WAP Projesine Sağ Tık > Publish"]
    Menu --> Opt1["1. Associate App with the Store..."]
    Menu --> Opt2["2. Convert Content Group Map File"]
    Menu --> Opt3["3. Create App Packages... (Ana İş Akışı)"]
    
    Opt1 --> Sync["Buluttaki Mağaza Kimliğini Yerel Manifest ile Senkronize Eder\n(Package.StoreAssociation.xml üretir)"]
    Opt2 --> Streaming["Akışlı Kurulum Harita Dosyasını Dönüştürür\n(Aşamalı indirme gerektiren devasa oyunlar için)"]
    Opt3 --> Wizards["Paket Üretim Sihirbazı:\n- Sideloading (Yerel QA Testleri)\n- Microsoft Store Yükleme Paketi (_bundle.appxupload)"]

1. Associate App with the Store... (Uygulamayı Mağaza ile İlişkilendir)

  • Amacı: Yerel Visual Studio çözümünüzü Microsoft Partner Center geliştirici hesabınızla doğrudan bağlar.
  • Ne Yapar: Geliştirici hesabınızla giriş yapıp rezerve ettiğiniz oyun adını seçersiniz. Visual Studio, Partner Center API'sine bağlanarak resmi Publisher ID, Package Name, Publisher Display Name ve Package Family Name (PFN) bilgilerini çeker ve Package.StoreAssociation.xml dosyasını oluşturur.
  • Neden Önemli: Bu ilişkilendirme yapılmazsa paketiniz geçici bir yerel sertifikayla imzalanır ve Partner Center yükleme sırasında kimlik uyuşmazlığı nedeniyle paketi reddeder.

2. Convert Content Group Map File (İçerik Grubu Harita Dosyası Dönüştürme)

  • Amacı: Microsoft'un Streaming Installation (Akışlı Yükleme) mimarisini destekler.
  • Ne Yapar: Devasa oyunlarda (örneğin 50+ GB AAA yapımlarda), oyuncunun oyunun ilk bölümünü oynarken kalan bölümlerin arka planda indirilmesine olanak tanır. Geliştiricinin yazdığı SourceAppxContentGroupMap.xml dosyasını derleme hattının anlayacağı nihai AppxContentGroupMap.xml dosyasına dönüştürür.
  • Bağımsız Oyunlar İçin Durumu: Tipik indie oyunlar için akışlı kurulum gereksizdir; bu seçeneği güvenle atlayabilirsiniz.

3. Create App Packages... (Uygulama Paketleri Oluştur - Ana Sihirbaz)

Oyununuzu yerel testler veya mağazaya yükleme amacıyla derlemek, imzalamak ve paketlemek için kullanılan ana araçtır.


4. Paket Oluşturma Sihirbazının Yapılandırılması

Publish \(\rightarrow\) Create App Packages... seçeneğine tıkladığınızda şu adımları izleyin:

Adım 1: Dağıtım Yöntemi Seçimi

  • Mağazaya Gönderim İçin: "Microsoft Store under a new or existing app name" seçeneğini işaretleyin. Bu seçenek paketi doğrulanmış bulut kimliğinize bağlar.
  • Yerel Test (Sideloading) İçin: "Sideloading" seçeneğini işaretleyin. Bu mod, geçici bir test sertifikası (.cer) ve PowerShell yükleme betiği (Add-AppDevPackage.ps1) ile başka bilgisayarlarda test edebileceğiniz bir paket üretir.

Adım 2: Paket Ayarları ve Mimari Yapılandırması

Yapılandırma penceresinde parametreleri belirleyin:

┌─────────────────────────────────────────────────────────────┐
│ Output location: .\AppPackages\                             │
│ Version: 1.0.0.0      [☑ Automatically increment]           │
│                                                             │
│ Generate app bundle: Always                                 │
│                                                             │
│ Mimariler:                                                  │
│   ☑ x86       Yapılandırma: Release (x86)                   │
│   ☑ x64       Yapılandırma: Release (x64)                   │
│   ☐ ARM       (Masaüstü Win32 oyunları için önerilmez)      │
│   ☐ ARM64     (Masaüstü Win32 oyunları için önerilmez)      │
│                                                             │
│ Seçenekler:                                                 │
│   ☑ Include public symbol files                             │
│   ☑ Generate artifacts to validate app with WACK            │
└─────────────────────────────────────────────────────────────┘

Sürüm Numaralandırma Mantığı:

Windows paketleri standart Semantik Sürümleme formatını izler: Major.Minor.Build.Revision.

  • İlk yayın genellikle 1.0.0.0 olarak başlar.
  • Küçük yamalarda revizyon artırılır (1.0.1.0), büyük özelliklerde ikincil veya birincil hane büyütülür (1.1.0.0, 2.0.0.0).
  • Katı Mağaza Kuralı: Partner Center'a yüklenen her yeni paketin sürüm numarası, mağazadaki aktif sürümden kesinlikle daha yüksek olmak zorundadır.
  • Automatically increment: Bu kutuyu işaretli bırakmak, her paket derlemesinde revizyon hanesini otomatik artırarak sürüm çakışmalarını engeller.

Neden x64 + x86 ve Generate app bundle: Always?

  • x64: Modern 64-bit Windows sistemlerini hedefler (PC oyuncularının %98'inden fazlası).
  • x86: Eski donanımlara sahip sistemler için geriye dönük uyumluluk sağlar.
  • Always Paketi: Visual Studio her iki mimariyi tek bir arşive (_bundle.appxupload) toplar; kullanıcılar yalnızca kendi sistemlerine uygun olan dosyaları indirir.

5. Package.appxmanifest Dosyasında Uzmanlaşma

Uygulama bildirimi; kimlik, çalışma yetkileri, görsel varlıklar ve ekran yönünü belirler:

<?xml version="1.0" encoding="utf-8"?>
<Package
  xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10"
  xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10"
  xmlns:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities"
  IgnorableNamespaces="uap rescap">

  <Identity
    Name="YourPublisher.YourGame"
    Publisher="CN=YOUR-OFFICIAL-PUBLISHER-ID"
    Version="1.0.0.0" />

  <Properties>
    <DisplayName>Oyununuzun Adı</DisplayName>
    <PublisherDisplayName>Stüdyo Adınız</PublisherDisplayName>
    <Logo>Images\StoreLogo.png</Logo>
  </Properties>

  <Dependencies>
    <TargetDeviceFamily Name="Windows.Universal" MinVersion="10.0.0.0" MaxVersionTested="10.0.0.0" />
    <TargetDeviceFamily Name="Windows.Desktop" MinVersion="10.0.17763.0" MaxVersionTested="10.0.26100.0" />
  </Dependencies>

  <Applications>
    <Application Id="App"
      Executable="$targetnametoken$.exe"
      EntryPoint="$targetentrypoint$">
      <uap:VisualElements
        DisplayName="Oyununuzun Adı"
        Description="MonoGame ile geliştirilmiş retro arcade nişancı oyunu."
        BackgroundColor="transparent"
        Square150x150Logo="Images\Square150x150Logo.png"
        Square44x44Logo="Images\Square44x44Logo.png">
        <uap:DefaultTile 
          Wide310x150Logo="Images\Wide310x150Logo.png"  
          Square71x71Logo="Images\SmallTile.png" 
          Square310x310Logo="Images\LargeTile.png" />
        <uap:SplashScreen Image="Images\SplashScreen.png" />
        <uap:LockScreen BadgeLogo="Images\BadgeLogo.png" Notification="badgeAndTileText"/>
        <uap:InitialRotationPreference>
          <uap:Rotation Preference="landscape"/>
        </uap:InitialRotationPreference>
      </uap:VisualElements>
    </Application>
  </Applications>

  <Capabilities>
    <Capability Name="internetClient" />
    <rescap:Capability Name="runFullTrust" />
  </Capabilities>
</Package>

Kritik Ayarlar:

  1. <rescap:Capability Name="runFullTrust" />: MonoGame WindowsDX; DirectX 11, donanım sürücüleri ve SharpDX/SDL üzerinden yerel Win32 çağrıları kullandığı için kısıtlı UWP sandbox'ında çalışamaz. runFullTrust izni, dosya yalıtımını korurken oyuna tam masaüstü çalıştırma yetkisi verir.
  2. InitialRotationPreference (landscape): Windows taşınabilir el konsolları (ASUS ROG Ally, Lenovo Legion Go vb.) dikey panellerle donatılmıştır. Ekran yönünün landscape olarak kilitlenmesi, oyunun yan veya ters açılmasını önler.

6. Görsel Varlık Ölçekleri ve BadgeLogo Kuralı

Windows Başlat Menüsü ve Görev Çubuğu farklı DPI çözünürlükleri (scale-100, scale-125, scale-150, scale-200, scale-400) kullanır. Eksik ölçekler bulanık simgelere veya doğrulama uyarılarına yol açar.

Varlık Türü Temel Boyut (scale-100) scale-200 scale-400 Açıklama
Square44x44Logo 44 x 44 px 88 x 88 px 176 x 176 px Görev çubuğu ve uygulama listesi simgesi
Square150x150Logo 150 x 150 px 300 x 300 px 600 x 600 px Orta boy Başlat Menüsü kutucuğu
Wide310x150Logo 310 x 150 px 620 x 300 px 1240 x 600 px Geniş Başlat Menüsü kutucuğu
LargeTile 310 x 310 px 620 x 620 px 1240 x 1240 px Büyük Başlat Menüsü kutucuğu
SmallTile 71 x 71 px 142 x 142 px 284 x 284 px Küçük Başlat Menüsü kutucuğu
SplashScreen 620 x 300 px 1240 x 600 px 2480 x 1200 px Başlangıç yükleme ekranı afişi
StoreLogo 50 x 50 px 100 x 100 px 200 x 200 px Mağaza kataloğu logo simgesi
BadgeLogo 24 x 24 px 48 x 48 px 96 x 96 px Kilit ekranı bildirim rozeti

Warning

Kilit Ekranı Rozeti (BadgeLogo) Kuralı: Kilit ekranı simgesi (BadgeLogo) kesinlikle yalnızca saf beyaz (#FFFFFF) ve şeffaf piksellerden oluşmalıdır. İçerisinde renkli pikseller veya ton geçişleri bulunursa, Windows Uygulama Sertifikasyon Kiti (WACK) kontrast uyumsuzluğu hatası vererek sertifikasyonu başarısız sayar.


7. Paket Doğrulama: WACK ve Sorun Giderme

Visual Studio derlemeyi tamamladığında Finished creating package ekranı açılır.

Yaygın Engel: "The tool AppCert.exe wasn't found" Hatası

Launch Windows App Certification Kit butonuna tıkladığınızda şu hata penceresiyle karşılaşabilirsiniz:

Microsoft Visual Studio:
The tool AppCert.exe wasn't found. Please ensure that the most recent 
installation of the Windows Software Development Kit includes the 
Windows App Certification Kit feature.

Neden Oluşur ve Nasıl Çözülür?

  • Visual Studio kurulumunda bazen WACK bileşeni seçilmemiş olabilir.
  • Çözüm: Visual Studio Installer \(\rightarrow\) Değiştir (Modify) \(\rightarrow\) Bağımsız Bileşenler (Individual components) sekmesine gidin \(\rightarrow\) "Windows App Certification Kit" araması yapıp kutuyu işaretleyin ve güncelleyin.
  • Alternatif: WACK testini yerel olarak çalıştırmak zorunlu değildir. Manifestiniz ve görselleriniz doğru yapılandırılmışsa, paketinizi doğrudan Microsoft Partner Center'a yükleyebilirsiniz; Microsoft'un bulut altyapısı bu sertifikasyon testlerini arka planda otomatik olarak yürütür.

MonoGame İkili Dosyalarında "Engellenen Yürütülebilir Dosya" Yanılgısı

WACK yerel testinde derlenmiş doku (.xnb) veya ses (.ogg) dosyalarınızın "Blocked Executables" başlığı altında listelendiğini görebilirsiniz.

Bu Neden Olur? Sıkıştırılmış oyun varlıklarındaki bayt dizilimleri tesadüfen çalıştırılabilir PE başlıklarına benzeyebilir. Bu dosyalar oyunun Content/ klasöründe statik varlık olarak bulunduğu ve doğrudan yürütülmediği sürece, Microsoft sertifikasyon ekibi bunları zararsız oyun içeriği olarak tanır ve mağaza onayını etkilemez.


8. Sideloading: Mağaza Öncesi Yerel Cihaz Testi

Paketi mağazaya göndermeden önce temiz bir bilgisayarda test edin:

  1. Üretilen test klasörüne gidin:
    AppPackages/YourGame_1.0.0.0_Test/
    
  2. Bu klasörde şunlar yer alır:
    • YourGame_1.0.0.0_x86_x64.appxbundle (veya .msixbundle)
    • YourGame_1.0.0.0_x86_x64.cer (Yerel geliştirici test sertifikası)
    • Add-AppDevPackage.ps1 (PowerShell kurulum betiği)
  3. PowerShell'i Yönetici Olarak Çalıştırın ve komutu yürütün:
    Set-ExecutionPolicy RemoteSigned -Scope Process
    .\Add-AppDevPackage.ps1
    
  4. Geliştirici sertifikasını güvenli kılmak için ekrandaki adımları onaylayın.
  5. Oyunu Başlat Menüsü'nden açarak kumanda kontrollerini, sesleri ve performansı konteyner ortamında doğrulayın.

9. Microsoft Partner Center Gönderim Kontrol Listesi

Hazırladığınız _bundle.appxupload dosyası ile Microsoft Partner Center paneline gidin:

Dashboard > Apps & Games > [Oyununuzun Adı] > Start submission
  1. Pricing and Availability (Fiyatlandırma ve Kullanılabilirlik): Pazar seçimini All worldwide markets (240 bölge) olarak belirleyin ve USD cinsinden taban fiyatı girin. Yerel para birimleri otomatik çevrilir.
  2. Properties & Privacy Policy: Kategoriyi Games yapıp alt türleri seçin. Manifest'te internetClient izni bulunduğu için çalışan bir Gizlilik Politikası URL'si (GitHub sayfası vb.) girin.
  3. Age Ratings (IARC Yaş Derecelendirmesi): Anketi gerçekçi doldurun. Arcade oyunlar genellikle doğrudan Everyone / PEGI 3 derecesi alır.
  4. Store Listings: 1920x1080 çözünürlükte PC oynanış ekran görüntüleri yükleyin (üzerinde mobil dokunmatik kontroller olmamalıdır).
  5. Packages: ..._bundle.appxupload dosyasını sürükleyip bırakın. Yeşil onayları aldıktan sonra Submit to the Store butonuna basarak incelemeyi başlatın.

10. MSBuild ile CI/CD Otomasyonu

GitHub Actions veya yerel betiklerle Visual Studio arayüzünü açmadan komut satırından paket üretmek için:

msbuild YourGame.Package\YourGame.Package.wapproj `
  /p:Configuration=Release `
  /p:Platform=x64 `
  /p:AppxBundlePlatforms="x86|x64" `
  /p:AppxBundle=Always `
  /p:UapAppxPackageBuildMode=StoreUpload `
  /p:AppxPackageDir=".\AppPackages\"

Bu komutu Microsoft Store Submission API ile birleştirerek, Git etiketleriniz üzerinden mağazaya otomatik güncelleme gönderebilirsiniz.


Sonuç

Bir MonoGame masaüstü oyununu Microsoft Store'da yayınlamak, kod tabanını UWP için yeniden yazmayı gerektirmez. Windows Uygulama Paketleme (WAP) projesi, tam güven (runFullTrust) yetkisi, standart ölçekli varlıklar ve hibrit x86|x64 paketleri ile modern, güvenilir ve küresel bir mağaza varlığı elde edebilirsiniz!