Ödüller
Bu sayfa oyunun oyuncuya verdiği ödüllerin Open Play’de nasıl tanımlandığını ve verildiğini anlatır: şansa bağlı ödül tabloları, günlük giriş ödülü, görevler, NPC ödülleri ve VIP kartları. Ödülün sunucuda, hile yapılamadan ve tek seferlik verilmesini istiyorsanız okuyun.
Ne işe yarar
Ödül modülü (rewards) “oyuncuya para ya da eşya ver” işini tek bir güvenilir hat üzerinden yapar. Her ödül verme işlemi tek bir veritabanı işlemidir: para cüzdana yazılır, eşya envantere konur ve olay kaydedilir. Envanter doluysa ya da para birimi arz tavanını aşarsa hiçbir şey verilmez (422).
Tablolu ödüller belirlenimcidir (deterministic): aynı tohum aynı sonucu verir. Tohum sunucuda tutulur; yanıtta, webhook olayında ve defter kaydında görünmez.
Modül kapalıysa uçlar 404 ve {"code":"module_disabled","module":"rewards"} döner. Modülü Oyun ayarları › Modüller sayfasından açın.
Panelde nerede
| Ne yapacaksınız | Panel sayfası |
|---|---|
| Ödül tablosu kurmak, satır şanslarını ve garanti ödülleri düzenlemek, sürümleri görmek | Ödül tabloları, Ödül tablosu profili |
| Ödülde kullanılacak para birimini tanımlamak | Para birimleri |
| Ödülde kullanılacak eşyayı tanımlamak | İçerik |
| Olay tetikli otomasyonla ödül vermek | Oyun kuralları |
Veri modeli (düz dille)
- Ödül tablosu:
key,name,rolls(kaç kez çekiliş yapılacağı, 1–10),entries(satırlar) veguaranteed(her seferinde verilen ödüller). Her kayıt yeni bir sürüm olur; grant sırasında güncel sürüm kullanılır ve sonuçta sürüm numarası döner. - Satır (entry):
chance_bp(baz puan, 1–10000) vedrop. Bir çekilişin satır şansları toplamı tam 10000 (%100) olmalıdır; “ödül yok” bir satır olabilir. - Ödül (
drop):currency(key,min,max),item(key,min,max) ya danothing. Adet her zamanminilemaxarasından eşit dağılımla seçilir; adetler 1 ile 1.000.000 arasındadır. Tabloda en çok 50 satır, 10 garanti ödül bulunur. - Garanti ödül: Çekilişten bağımsız verilir;
nothingolamaz. - Kaynak (
source): Ödülün neden verildiğini tipli olarak yazar:content_entry,tournament,leaderboard_season,quest,npc_reward,ruleya damanual.
Oyunun yaptığı çağrılar
Tüm ödül uçları sunucu anahtarıyla (ya da yönetici türünde bir anahtarla) çağrılır; istemci anahtarı ve oyuncu oturumu reddedilir. Oyuncu kimliği güvenilir sunucu bileşeninin gövdesinde taşınır:
Authorization: Bearer crx_live_<önek>_<gizli>
| Yöntem ve yol | Ne yapar |
|---|---|
POST /v1/reward-tables | Ödül tablosunu yeni sürüm olarak kaydeder |
GET /v1/reward-tables/{key} | Güncel sürümü okur |
POST /v1/reward-tables/{key}/grant | Tablodan idempotent ödül verir |
GET /v1/login-rewards/{player_id} | Bugünün giriş ödülü durumunu okur |
POST /v1/login-rewards/{player_id}/claim | Günlük giriş ödülünü verir |
POST /v1/quests | Görev tanımı kaydeder |
GET /v1/quests, GET /v1/quests/{key} | Görevleri listeler / okur |
POST /v1/quests/{key}/claim | Görev dönemi ödülünü verir |
GET /v1/npc-rewards/{key}/eligibility | NPC ödülü uygunluğunu okur (yazmaz) |
POST /v1/npc-rewards/{key}/claim | NPC ödülünü verir |
GET /v1/vip/{player_id} | VIP katmanını okur |
POST /v1/vip/{player_id}/cards/{item_instance_id}/use | VIP kartı kullanır |
Not
TypeScript SDK’sında yalnız ödül tablosu için tipli istemci vardır (
CrxClient.createRewardTable,getRewardTable,grantRewardTable). Giriş ödülü, görev, NPC ve VIP uçları ham REST ile çağrılır. Bkz. TypeScript SDK.
Ödül tablosu kaydetmek
POST /v1/reward-tables
Authorization: Bearer crx_live_<önek>_<gizli>
Content-Type: application/json
{
"key": "welcome_pack",
"name": "Hoş geldin paketi",
"rolls": 1,
"entries": [
{ "chance_bp": 7000, "drop": { "type": "currency", "key": "gold", "min": 100, "max": 300 } },
{ "chance_bp": 2500, "drop": { "type": "item", "key": "health_potion", "min": 1, "max": 3 } },
{ "chance_bp": 500, "drop": { "type": "nothing" } }
],
"guaranteed": [ { "type": "currency", "key": "gold", "min": 50, "max": 50 } ]
}
Yanıt 201 ve { id, version, key, name, rolls, entries, guaranteed, created_at_ms } döner; çekiliş tohumu hiçbir yanıtta bulunmaz. Şans toplamı 10000 değilse, tablo boşsa ya da sınırlar aşılıyorsa kayıt 422 ve düz metin iletiyle reddedilir. validate anahtarı ayrılmıştır, tablo anahtarı olarak kullanılamaz.
Tablodan ödül vermek
POST /v1/reward-tables/welcome_pack/grant
Authorization: Bearer crx_live_<önek>_<gizli>
Idempotency-Key: welcome-oyuncu-1234
Content-Type: application/json
{ "player_id": "0192f0f2-5b1a-7c3e-9d11-4a5b6c7d8e9f", "source": { "type": "manual", "operator_id": "game-server" } }
{
"grant_id": "…", "tx_id": "…", "event_id": "…",
"table_key": "welcome_pack", "table_version": 1,
"rewards": [ { "drop": "currency", "key": "gold", "quantity": 250 }, { "drop": "item", "key": "health_potion", "quantity": 2 } ],
"replayed": false
}
Idempotency-Key zorunludur. Aynı anahtar ve aynı gövde ödülü ikinci kez vermez; ilk sonuç replayed: true ile döner. Aynı anahtar farklı gövdeyle 422’dir. source değişkenleri:
type | Ek alanlar |
|---|---|
manual | operator_id |
content_entry | group, entry |
quest | quest_key |
npc_reward | npc_key |
tournament | tournament_id, placement |
leaderboard_season | leaderboard_key, season |
rule | rule_key, event_id |
Para ve eşya tek işlemde verilir: envanter doluysa ya da para birimi arz tavanı aşılırsa bütün verme geri alınır ve 422 döner. Oyuncuya bağlı olmayan bir karakter için NPC ödülü verilemez.
Günlük giriş ödülü
GET /v1/login-rewards/{player_id} bugünün durumunu verir: period_date, claimed, streak_day, current_streak, config_version. POST /v1/login-rewards/{player_id}/claim ödülü verir ve { period_date, streak_day, rewards, event_id, tx_id, replayed } döner; aynı gün ikinci çağrı aynı makbuzu replayed: true ile geri verir, ikinci ödül vermez.
Gün, ortamın saat dilimine (timezone, Ortamlar ve alan adları) göre hesaplanır. Ödül çizelgesi (gün sayısı, her günün para ödülü) ve kaçırılan gün politikası (reset_on_miss: seri 1’e döner; freeze: seri korunur) sürümlü bir yapılandırmadır.
Not
Giriş ödülü yapılandırmasını (çizelge ve seri politikası) yazan herkese açık bir uç ya da panel ekranı henüz yoktur; yapılandırma şimdilik Open Play operatörü tarafından kurulur.
Görevler
POST /v1/quests görev tanımını yeni sürüm olarak kaydeder:
{
"key": "kill_10_wolves",
"name": "On kurt avla",
"objectives": [ { "key": "wolves", "event_type": "event_emitted", "count": 10, "filter_cel": "event.event_key == \"wolf_killed\"" } ],
"rewards": [ { "type": "currency", "key": "gold", "amount": 500 }, { "type": "table", "key": "welcome_pack" } ],
"recurrence": "daily"
}
objectives[].event_type: görevi ilerleten olay türü (karakter olayları,score_submitted,login, eşya ve para olayları gibi);countkaç kez gerektiği;filter_celisteğe bağlı koşul.rewards[].type:currency(key,amount) ya datable(ödül tablosu anahtarı).recurrence:none,daily,weekly.windowveprerequisite_cel(kayıt anında derlenir) isteğe bağlıdır.POST /v1/quests/{key}/claimgövdesi{ "player_id": "…", "period_key": "…" }’dir (period_keyen çok 160 karakter). Yanıt{ status: "claimed" | "already_claimed", reward_count, event_id }— aynı dönemi ikinci kez almakalready_claimeddöner, ödül tekrarlanmaz.GET /v1/questssearch,limit,offsetile listeler (sayfa içitotaldöner).
Not
Görev ilerlemesini (oyuncunun hangi görevde kaçta olduğunu) okuyan herkese açık bir REST ucu henüz yoktur. İlerleme olaylardan sunucuda hesaplanır;
period_keydeğerini bu nedenle oyun sunucunuzun kendisi bilmelidir.
NPC ödülleri
GET /v1/npc-rewards/{key}/eligibility?character_id=…&period_key=… yazmadan uygunluğu söyler: { eligible, reason } (reason: cooldown, daily_limit, condition). POST /v1/npc-rewards/{key}/claim (Idempotency-Key zorunlu, gövde { "character_id", "period_key" }) ya ödülü verir ya da rejected döner: { status: "claimed" | "rejected", reward_count, claim_count, tx_id, reason }. NPC kuralını (bekleme, günlük sınır, CEL koşulu, ödül) kaydeden herkese açık bir uç henüz yoktur.
VIP
VIP katmanı kümülatif puandan türetilir. GET /v1/vip/{player_id} { player_id, cumulative_points, tier, config_version } verir. POST /v1/vip/{player_id}/cards/{item_instance_id}/use (Idempotency-Key zorunlu) bir vip_card eşyasını tüketir ve puan ekler; kart bir üst katman koşulunu (mevcut katman + 1) karşılamıyorsa 422 döner. İstemci ve sunucu anahtarı aynı VIP yüzeyini kullanabilir.
Sürümleme ve tekrar güvenliği
- Tablo grant, NPC claim ve VIP kart kullanımı:
Idempotency-Keyzorunlu. - Giriş ödülü: aynı gün ikinci claim aynı makbuzu döner; başlık gerekmez.
- Görev claim: dönem anahtarı doğal tekrar güvenliğidir (
already_claimed). - Tablo ve görev kayıtları her seferinde yeni sürümdür; eski sürümler değişmez.
- Genel kurallar: Idempotency ve eşzamanlılık.
Olaylar ve webhook’lar
Tablodan veya sabit para ile verilen her ödül reward_granted olayı üretir ve webhook olarak gönderilebilir. Zarfta event_id, environment_id, player_id, type ve data (source_kind, table_key, table_version ve verilenler) bulunur; tohum yoktur. Kayıt ve doğrulama: Webhook’lar.
Sınırlar
- Tabloda en çok 50 satır, 10 garanti ödül, 10 çekiliş (
rolls); adetler 1–1.000.000. chance_bptoplamı tam 10000.- Görev
period_keyveclaimalanları en çok 160 karakter.
Sık görülen hatalar
| Belirti | Neden | Çözüm |
|---|---|---|
403 | İstemci anahtarı ya da oyuncu oturumuyla çağrı | Çağrıyı sunucu anahtarıyla, sunucunuzdan yapın |
422 (tablo kaydı) | Şanslar 10000’e tamamlanmıyor ya da sınır aşıldı | Satırları düzeltin; nothing satırıyla tamamlayın |
422 envanter dolu | Verilecek eşya için boş yuva yok | Oyuncuya yer açtırın; işlem hiç yazılmadı, tekrar denenebilir |
422 arz tavanı | Para birimi max_supply sınırı | Tavanı panelden yükseltin |
422 idempotency mismatch | Aynı anahtar, farklı gövde | Yeni anahtar kullanın |
404 tablo yok | key yanlış ya da tablo henüz kaydedilmedi | GET /v1/reward-tables/{key} ile doğrulayın |
Çalışan örnek
Hoş geldin tablosundan para verme ve ardından mağazadan alma akışı Ekonomi sayfasındadır. TypeScript’te crx.grantRewardTable("welcome_pack", { playerId, source, idempotencyKey }) çağrısı aynı uca gider; idempotencyKey verilmezse SDK çağrı başına üretir, ağ tekrarında aynı anahtarı kendiniz vermelisiniz.