İstek Listesi
🚀 FELEROUS PLAYZONE ECOSYSTEM

Felerous Arcade SDK v2.0 Rehberi

HTML5 Canvas ve WebGL oyunlarınızı PlayZone platformuna bağlayarak binlerce oyuncuya sıfır indirmeyle ulaştırın. Gerçek zamanlı skor telemetrisi, 18 kademeli profil başarımları ve otomatik CDN optimizasyonu.

⚡ 1. 5 Dakikada Hızlı Başlangıç

Felerous Arcade ekosisteminin felsefesi: "Oyun akıcı çalışır (Dumb Engine), Platform skorları ve başarımları akıllıca yönetir (Smart Platform)."

💡
Oyununuzda yapmanız gereken tek şey: HTML dosyanıza felerous-bridge.js köprüsünü dahil etmek ve oyuncu başarım kazandığında ya da oyun bittiğinde ilgili fonksiyonu çağırmaktır.
index.html (Entegrasyon Kodu)
<!-- 1. Oyunun içine köprüyü ekleyin -->
<script src="js/felerous-bridge.js"></script>

<script>
  // 2. Sayfa açıldığında köprüyü başlatın
  felerousBridge.init();

  // 3. Oyuncu bir başarım kazandığında anında tetikleyin:
  felerousBridge.unlockAchievement('first_clear');

  // 4. Oyun bittiğinde skoru platforma iletin:
  felerousBridge.submitScore({
    score: 18450,
    difficultyTier: 'lvl2',
    difficultyLabel: 'Klasik',
    durationSeconds: 120,
    achievements: ['first_clear'],
    stats: { lines_cleared: 15, apm: 90 }
  });
</script>

📁 2. Evrensel Klasör Standardı

Cloudflare R2 kovanına yüklenecek olan oyun paketinizin kök dizini standart ve temiz olmalıdır:

Dosya ve Dizin Hiyerarşisi
[oyun-slug-kodu]/                      (Örn: dusen-sicimler/)
├── index.html                         # Oyunun giriş noktası (HTML5 Canvas)
├── manifest.json                      # [ZORUNLU] Oyun kimliği, tür ve yönlendirme
├── achievements.json                  # [ÖNERİLEN] Oyunun tüm başarımları (v1.0.1)
├── changelog.json                     # [OPSİYONEL] Sürüm geçmişi (FDB Depo sekmesinde gösterilir)
├── icon.png                           # 512x512 kare vitrin ikonu
├── cover.png                          # Dikey kapak görseli (600x900)
├── banner.png                         # Geniş afiş görseli (1920x1080)
├── css/
│   └── style.css                      # Oyun stilleri (100dvh ve koyu mod korumalı)
└── js/
    ├── felerous-bridge.js             # Felerous Store resmi köprü SDK'sı
    ├── sound.js                       # 8-bit prosedürel Web Audio motoru
    └── game.js                        # Oyun mantığı ve döngüsü
⚠️
R2 Temizlik Kuralı: Dağıtım klasörünüzde kesinlikle server.js, node_modules/, .git/ veya geçici geliştirici notları bulunmamalıdır. Sadece tarayıcının doğrudan çalıştıracağı saf dosyalar yer almalıdır.

📄 3. MANIFEST.JSON Spesifikasyonu

Platformun oyunu otomatik tanıması, vitrine eklemesi ve FDB veri tabanında depoları listelemesi için kök dizinde manifest.json bulunmalıdır:

manifest.json Şablonu
{
  "id": "dusen_sicimler",
  "slug": "dusen-sicimler",
  "name": "Düşen Sicimler",
  "version": "1.0.1",
  "developer": "Subushaki",
  "publisher": "FELEROUS",
  "category": "Arcade",
  "game_type": "web",
  "entry": "index.html",
  "icon": "icon.png",
  "cover": "cover.png",
  "banner": "banner.png",
  "orientation": "portrait_or_landscape",
  "resolution": {
    "width": 1080,
    "height": 1920,
    "responsive": true
  },
  "features": {
    "achievements": true,
    "leaderboards": true,
    "anti_cheat": true,
    "telemetry": true
  }
}
Alan Tür Açıklama
id String Veritabanı ve API ile eşleşen benzersiz kimlik (snake_case).
slug String URL ve R2 klasör adı (kebab-case).
orientation String Mobil yön tercihi: "portrait", "landscape" veya "portrait_or_landscape".
features Object Oyunun desteklediği platform özellikleri (başarımlar, liderlik vb.).

🏆 4. ACHIEVEMENTS.JSON Spesifikasyonu (v1.0.1)

Felerous Store ekosisteminde başarımların tek doğru kaynağı (Single Source of Truth) oyun kökündeki achievements.json dosyasıdır. FDB ve Profil sayfaları bu veriyi okur.

achievements.json Örneği (Düşen Sicimler)
{
  "game_id": "dusen_sicimler",
  "version": "1.0.1",
  "total": 8,
  "achievements": [
    {
      "id": "first_clear",
      "title": "İlk Adım",
      "description": "İlk satırını başarıyla temizle.",
      "icon": "🧱",
      "category": "progression",
      "rarity": "common",
      "points": 10
    },
    {
      "id": "tetris_master",
      "title": "Düşen Sicim",
      "description": "Tek hamlede 4 satır birden sil.",
      "icon": "⚡",
      "category": "skill",
      "rarity": "rare",
      "points": 25
    },
    {
      "id": "combo_king",
      "title": "Kombo Ustası",
      "description": "En az 4x ardışık satır kombosu yap.",
      "icon": "🌪️",
      "category": "skill",
      "rarity": "epic",
      "points": 50
    },
    {
      "id": "hard_dropper",
      "title": "Işık Hızı",
      "description": "Tek oyunda 25 kez sert düşüş (smash) yap.",
      "icon": "💥",
      "category": "speed",
      "rarity": "uncommon",
      "points": 15
    },
    {
      "id": "survivor",
      "title": "Kabus Gazisi",
      "description": "Kabus modunda en az 60 saniye hayatta kal.",
      "icon": "🛡️",
      "category": "survival",
      "rarity": "legendary",
      "points": 100
    },
    {
      "id": "architect",
      "title": "Büyük Mimar",
      "description": "Tek bir oyunda 50+ satır sil.",
      "icon": "👑",
      "category": "endurance",
      "rarity": "epic",
      "points": 50
    },
    {
      "id": "high_scorer",
      "title": "Puan Avcısı",
      "description": "Tek bir oyunda 20.000 puanı aş.",
      "icon": "🎯",
      "category": "score",
      "rarity": "rare",
      "points": 30
    },
    {
      "id": "tactician",
      "title": "Usta Taktisyen",
      "description": "Hold (saklama) özelliğini en az 10 kez kullan.",
      "icon": "🔄",
      "category": "strategy",
      "rarity": "uncommon",
      "points": 15
    }
  ]
}

🔌 5. Resmi Köprü SDK: felerous-bridge.js

Oyununuz ile PlayZone çerçevesi arasındaki tüm iletişimi yöneten hazır sınıf. Doğrudan projenize kopyalayabilirsiniz:

js/felerous-bridge.js
/**
 * FELEROUS ARCADE KÖPRÜSÜ (SDK v2.0)
 * Parent iframe ile tam uyumlu postMessage iletişim protokolü.
 */
class FelerousArcadeBridge {
    constructor(gameId = 'dusen_sicimler') {
        this.gameId = gameId;
        this.player = null;
        this.isEmbedded = window.self !== window.top;
        this.setupListeners();
    }

    init() {
        if (this.isEmbedded) {
            window.parent.postMessage({
                type: 'FELEROUS_INIT_PLAYER',
                game_id: this.gameId
            }, '*');
        }
    }

    setupListeners() {
        window.addEventListener('message', (event) => {
            const data = event.data;
            if (!data || typeof data !== 'object') return;

            switch (data.type) {
                case 'FELEROUS_PLAYER_INFO':
                    this.player = {
                        name: data.player_name || 'Oyuncu',
                        avatar: data.avatar_url || '',
                        felerousId: data.felerous_id || null
                    };
                    break;
                case 'FELEROUS_SET_MUTE':
                    if (typeof window.sound !== 'undefined' && typeof window.sound.setMute === 'function') {
                        window.sound.setMute(data.muted);
                    }
                    break;
                case 'FELEROUS_PAUSE':
                    if (typeof window.game !== 'undefined' && typeof window.game.togglePause === 'function') {
                        window.game.togglePause(true);
                    }
                    break;
                case 'FELEROUS_RESUME':
                    if (typeof window.game !== 'undefined' && typeof window.game.togglePause === 'function') {
                        window.game.togglePause(false);
                    }
                    break;
            }
        });
    }

    /**
     * Başarım Kilidi Açma (Anında çağrılır ve Supabase'e yazar)
     */
    unlockAchievement(achievementId) {
        if (!achievementId) return;
        const payload = {
            type: 'FELEROUS_UNLOCK_ACHIEVEMENT',
            game_id: this.gameId,
            achievement_id: achievementId
        };
        try {
            window.parent.postMessage(payload, '*');
        } catch (e) {
            console.warn('[Felerous Arcade] Başarım iletim hatası:', e);
        }
    }

    /**
     * Skor Bildirimi (Oyun bittiğinde çağrılır)
     */
    submitScore({
        score = 0,
        levelReached = 1,
        linesCleared = 0,
        difficultyTier = 'lvl2',
        difficultyLabel = 'Klasik',
        durationSeconds = 0,
        achievements = [],
        stats = {}
    }) {
        const payload = {
            type: 'FELEROUS_SUBMIT_SCORE',
            game_id: this.gameId,
            score: Math.max(0, Math.floor(score)),
            level_reached: levelReached,
            lines_cleared: linesCleared,
            difficulty_tier: difficultyTier,
            difficulty_label: difficultyLabel,
            duration_seconds: Math.max(0, Math.floor(durationSeconds)),
            achievements: achievements,
            stats: {
                lines_cleared: linesCleared,
                ...stats
            }
        };

        try {
            window.parent.postMessage(payload, '*');
        } catch (e) {
            console.error('[Felerous Arcade] Skor iletim hatası:', e);
        }
        return payload;
    }

    exitToPlayzone() {
        const targetUrl = 'https://store.felerous.com/playzone';
        try {
            window.parent.postMessage({
                type: 'FELEROUS_EXIT_GAME',
                game_id: this.gameId,
                redirect_url: targetUrl
            }, '*');
        } catch (e) {}

        setTimeout(() => {
            if (window.top && window.top !== window.self) {
                window.top.location.href = targetUrl;
            } else {
                window.location.href = targetUrl;
            }
        }, 100);
    }
}

// Global köprü örneği
const felerousBridge = new FelerousArcadeBridge('dusen_sicimler');

📱 6. Mobil & Çapraz Tarayıcı "Altın Kuralları"

Mobil tarayıcılarda (Safari, Samsung Internet, Chrome Mobil) kusursuz deneyim sağlamak için şu 4 kural uygulanmalıdır:

1. Dynamic Viewport (100dvh)

Mobil gezinti çubuğu hareket ettiğinde sayfanın taşmasını engeller:

css/style.css
html, body, #game-container {
  height: 100vh;
  height: 100dvh;
  height: -webkit-fill-available;
  overflow: hidden;
  position: fixed;
  width: 100%;
}

2. SafeStorage (Safari Gizli Mod & Iframe Koruması)

Safari Gizli Modunda localStorage çökmelerini engeller:

SafeStorage Koruması
window.SafeStorage = {
  _mem: {},
  getItem(k) {
    try { return localStorage.getItem(k); }
    catch (e) { return this._mem[k] || null; }
  },
  setItem(k, v) {
    try { localStorage.setItem(k, v); }
    catch (e) { this._mem[k] = String(v); }
  }
};

3. Web Audio API Otomatik Oynatma Uyandırıcısı (unlockAudio)

Kullanıcının ilk dokunuşunda ses motorunu uyandırır:

unlockAudio Snippet
function unlockAudio() {
  if (window.audioCtx && window.audioCtx.state === 'suspended') {
    window.audioCtx.resume();
  }
  document.removeEventListener('pointerdown', unlockAudio);
}
document.addEventListener('pointerdown', unlockAudio, { passive: true });

4. Samsung Internet Renk Bozulması Koruması

Gece modunda canvas renklerinin tersine çevrilmesini engeller:

Zorunlu Gece Modu Koruması
:root { color-scheme: dark; }
canvas { color-scheme: dark; forced-color-adjust: none; touch-action: none; }

🧪 7. İnteraktif JSON Doğrulayıcı

Oyununuzu R2'ye yüklemeden önce manifest.json veya achievements.json dosyanızı buraya yapıştırıp şema geçerliliğini anında test edebilirsiniz:

manifest.json şeması kontrol edilecek.