Geliştiriciler için · @camtable/sdk

Görüntülü aramanın içinde oynanan oyunu sen yaz.

Kurallar senin, barındırma senin. Masa, koltuklar, kameralar ve fısıltılar CamTable'ın: oyun sayfan Discord Web aramasının üstünde, arkadaşlarının kameralarıyla birlikte açılır.

  • Tek paket: @camtable/sdk
  • CamTable'a yükleme yok, inceleme yok
  • Host modunda maliyet sıfır
Bir aramanın katmanları
  1. Katılım onayı CamTable Oyuncu katılmadan önce izinlerini görür.
  2. Kutucuk HUD'u CamTable Puan, sıra ve fısıltı kutucukların üstünde. z-index 95000
  3. Senin oyun sayfan Sen Oyuncuların kameraları senin yuvalarında. z-index 90000
  4. Discord Web araması Discord Video ızgarası ve kontroller yerinde kalır.

Üstten alta. Sayfanın boş alanına yapılan tıklama aramaya geçer.

Hızlı başlangıç

İskeleti kur, Inspector'da oyna.

Yakında npm'de @camtable/sdk ve create-camtable-addon herkese açık betayla npm'e gelecek. Komutlar o gün böyle çalışacak; rehber şimdiden hazır.

Terminal
pnpm create camtable-addon my-game            # host mode: static files only, free to host
pnpm create camtable-addon my-game --engine   # engine mode: one Worker serves the pages and your engine
cd my-game
pnpm install
pnpm dev                                      # then open the Inspector link it prints
  1. İskeleti seç

    Bayraksız komut host modunda bir proje kurar: yalnızca statik dosyalar. --engine ile sayfaların ve motorun tek bir Cloudflare Worker'da durur.

  2. pnpm dev çalıştır

    Eklentin geçici bir https tünelinin arkasına geçer. Komut, manifest adresi dolu bir Inspector bağlantısı ve gerçek bir arama için bir Kurulum Bağlantısı yazar.

  3. Her koltukta oyna

    Inspector'da Discord ile giriş yap, bir Test Odası aç ve maçın bütün oyuncularını kendin oyna.

pnpm dev çıktısı
  Manifest URL  https://<random-words>.trycloudflare.com/manifest.json
  Inspector     https://camtable.app/inspector?url=<manifest url>
  Install link  https://camtable.app/install?url=<manifest url>

Bir oyunu çevrimdışı denemenin yolu yok: oda CamTable'ın sunucusunda çalışır ve eklentine yalnızca https ile ulaşır. Tünel bu yüzden var. Çevrimdışı çalışan, testlerin.

İskelette ne var

src/game.ts
Kurallar, saf bir reducer olarak. İki modda da aynı nesne çalışır.
src/addon.ts
Manifest ve bütün protokol rotaları. İlk iş ADDON_ID sabitini değiştir.
index.html, src/main.ts
Oyun sayfası: Tap Race, ilk on dokunuşa ulaşan kazanır.
tests/
Reducer, baştan sona bir maç ve her rota. Hiçbiri ağ istemez.

Kod

Kuralları bir kez yaz.

SDK'nın README'sinden, olduğu gibi: oyun sayfası SDK'yı açar, kurallar odayı açan oyuncunun sayfasında işler. Bu host modu; motor gerekmez.

Oyun sayfası · host modu
import { CamTableSDK, createHostAuthority, rng } from "@camtable/sdk";

const sdk = new CamTableSDK();
createHostAuthority(
  {
    apply: ({ state, action, playerId }) => {
      const roll = rng(`${state.seed}:${state.moves}`).int(1, 6); // reproducible, not secret
      return { state: { ...state, moves: state.moves + 1, roll } };
    },
  },
  { sdk },
);
await sdk.init();
createHostAuthority
Reducer'ını oda sahibinin sayfasında çalıştırır ve yanıtı odaya işler. Başka bir oyuncunun sayfasında istekleri yok sayar; bu yüzden koşulsuz çağırırsın.
apply
Durum, hamle ve hamleyi yapan oyuncu girer; { state, views?, rejected?, timers?, gameOver? } çıkar. Yanıt iki modda da aynı.
rng(seed)
Tohumlu bir üreteç. Reducer saate ya da Math.random çağrısına bakmaz; tohumu durumda tutarsın, aynı istek her yerde aynı yanıtı verir.
sdk.init()
Sayfa host olduğunu ancak init yerel oyuncuyu adlandırınca bilir. Sayfa bir odanın dışında açılırsa NotInRoomError Inspector'ın adresini verir.

Sayfanın geri kalanı iki çağrı: sdk.onStateChange ile odanın yayınladığını çizersin, sdk.sendAction ile oyuncunun yaptığını gönderirsin. Bir hamle her zaman bir istektir, asla bir durum değil. 2,5 saniyede yanıt vermeyen, hata atan ya da başka bir şey döndüren reducer reddedilir; sıradaki hamle bekletilmez.

Host modu ve engine modu

Kurallar nerede işlesin? Tek satır karar verir.

Play Option bir engine adresi bildiriyorsa oyun engine modunda, bildirmiyorsa host modunda çalışır. Başka bir anahtar yok. Reducer iki modda da aynı, mod değiştirmek yalnızca bir yapılandırma işi.

Host modu

Varsayılan
Kuralları kim işletir
Odayı açan oyuncunun, yani oda sahibinin tarayıcısı.
Kim hile yapabilir
Yalnızca oda sahibi. Diğerleri yalnızca istek gönderir.
Gizli bilgi
Oda sahibi hepsini görür; diğerleri yalnız kendi görünümünü.
Rastgelelik
Oda sahibinin elinde: rng tekrarlanabilir, adil değil.
Ne barındırırsın
Yalnızca statik dosyalar.
Maliyetin
Sıfır. Cloudflare'de statik dosyalar ücretsiz ve sınırsız.
Katılım onayında yazan
Kuralları oda sahibinin tarayıcısı işletir (gizli bilgileri görebilir)

Arkadaşlar arasında rahat bir oyun için host modu.

Engine modu

engine.url
Kuralları kim işletir
Senin sunucun. CamTable'ın odası onu imzalı HTTP ile çağırır.
Kim hile yapabilir
Kimse yapamaz, oda sahibi de.
Gizli bilgi
Herkesten gizli kalır.
Rastgelelik
Senin elinde: oda sahibi etkileyemez.
Ne barındırırsın
Sayfalar ve bir motor. İskelette ikisi tek bir Worker.
Maliyetin
Hamle ya da zamanlayıcı başına bir motor çağrısı. Cloudflare'in ücretsiz planı günde 100.000 Worker çağrısı verir.
Katılım onayında yazan
Kuralları <motorunun adresi> sunucusu işletir

Gizli bir el, gizli bir rol ya da iddialı bir maç için engine modu.

CamTable'ın Resmî Eklentisi de bu paketle yazıldı ve aynı protokolle gelir; ayrıcalıklı bir yolu yok. 14 oyunu engine modunda, Dice Duel host modunda çalışır.

SDK sana ne verir

Zor kısımlar CamTable'da.

Bir aramada oyun oynatmanın zor kısımlarını CamTable taşır; sen birkaç çağrı yaparsın. İsimler, kutucuklar, fısıltılar, mikrofon ve kamera, yalnızca manifestinde bildirdiğin izinle açılır.

  • Koltuklar ve oyuncular

    İzin: players.profile

    sdk.init() odayı, yerel oyuncuyu ve masadakileri verir. Her oyuncu maça özel bir Match Player Id'dir (mp_…); Discord kimliği, sunucu ya da kanal oyununa hiç ulaşmaz. İsim ve avatar için izin gerekir.

  • Video yuvaları

    Bir öğeyi oyuncunun kimliğiyle işaretle (data-camtable-video), CamTable o oyuncunun kamerasını tam o kutuya çizer. Görüntü sayfanın üstünde durur; pikselleri hiç ellemezsin.

  • Kutucuk katmanları

    İzin: tiles.overlay

    Oyuncuların arama kutucuklarına rozet, sayaç, zamanlayıcı, durum satırı ve düğme koy. Kutucuktaki bir düğmeye basılınca sayfan bunu onTileAction ile duyar.

  • Fısıltılar

    İzin: whisper

    Kuralların grupları adlandırır ya da sayfan oyuncu adına Fısıltı İsteği yapar. Ses tarayıcıdan tarayıcıya gider. Kimin kiminle fısıldaştığını bilirsin, ne konuşulduğunu asla.

  • Mikrofonu ve kamerayı masaya kapatma

    İzinler: call.mute , call.cover

    Gece evresinde oyuncunun sesini aramaya kapat (setCallMuted), kameraları durumdaki callCover ile karart, bulanıklaştır ya da son karede dondur. Maç sürerken oyuncu açamaz ve bunu yalnız kendisi görür.

  • Oyun ayarları ve Lobi

    Alanları tanımla: sayı, açma-kapama, tek seçim, çoklu seçim. Formu CamTable çizer; oda sahibi maçtan önce Lobide seçer, kuralların seçimleri her istekte settings olarak alır. Play Option başına en fazla 24 alan.

  • Özel sekmeler

    İstatistik ya da maç geçmişi gibi ek sayfalar, oyunun üst çubuğundan açılan çekmecede durur. Oyun ve sekme, oyuncunun tarayıcısında kalan sekme durumuyla konuşur.

  • Katmanlar ve tıklama geçişi

    Sayfan aramanın üstünde şeffaf bir katman. Boş alan tıklamayı Discord'a geçirir, yalnız senin öğelerin tıklama alır. SDK düğmeleri ve etkileşimli öğeleri kendisi ölçüp bildirir; canvas için bölgeleri sen yazarsın.

Inspector ve Test Odaları

Arama açmadan her koltukta kendin oyna.

Inspector, CamTable sitesinde bir sayfa. Eklentinin https manifest adresini yapıştır, bir oyun ve Play Option seç, bir Test Odası aç. Ne Discord araması gerekir ne CamTable'ın Chrome eklentisi; Discord ile giriş yapman yeter.

  • Gerçek sunucuda gerçek bir oda. Lobi, oyun ayarları, odanın sınırları ve engel listesi her odadaki gibi işler, iki modda da.
  • Her koltuk ayrı bir oyun çerçevesi: kendi oda bağlantısı, kendi Match Player Id'si ve yer tutucu bir video kutucuğu. İlk koltuk oda sahibidir.
  • Engine modunda oda, motorunu CamTable'ın gerçek imzasıyla çağırır. İstek "test": true taşır; istatistik tutuyorsan bu maçı dışarıda bırakırsın.
  • Olay günlüğü, her koltuğun sayfasının yaptığı köprü çağrılarını ve kurallarının reddettiği hamleleri gösterir.
  • Ücretli plan gerekmez. Odaya yalnız sen girersin, hiçbir yerde listelenmez ve 30 dakika sonra kapanır. Aynı anda bir tane açabilirsin.
Çizim: Inspector'da üç koltuklu bir Test Odası. Her koltukta oyunun kendi çerçevesi, altında her oyuncu için bir yer tutucu video kutucuğu.

Güvenlik modeli

Kapalı kutuda çalışır, izinle konuşur.

Oyuncular senin kodunu kendi Discord oturumlarının yanında çalıştırır. Bu yüzden sınırlar baştan çizili.

  • Opak sandbox

    Oyun sayfan sandbox="allow-scripts" olan, kökeni opak bir çerçevede açılır. Discord'un sayfasını, çerezlerini ya da depolamasını okuyamaz, eklentinin API'lerine erişemez. Kamera görüntüsü ve mikrofon sesi sayfana hiç gelmez.

  • İzinler

    Köprünün her yeteneği, manifestinde bildirdiğin bir izin ister. Bildirmediğin bir çağrı PERMISSION_DENIED ile reddedilir. Az iste: her izin, oyuncunun karar vermeden önce okuduğu bir satır.

  • Katılım onayı

    Oyuncu katılmadan önce eklentinin adını, kökenini, izinlerini ve kuralları kimin işlettiğini görür; CamTable'ın eklentiyi barındırmadığını ve incelemediğini de. Hayır diyen aramada kalır, oyun onun için açılmaz.

  • Engel listesi

    CamTable'ın uzaktan engel listesindeki bir eklenti yüklenemez, başlatılamaz, katılınamaz ve motoru hiç çağrılmaz. Hak sahiplerinin kabul edilen bildirimleri listeye girer.

Eklenti protokolü

Arada mağaza yok. Eklentin senin adresinde.

Bir eklenti, senin barındırdığın ve kendini bir manifest.json ile tanıtan bir servis. Rotalar Stremio'nun şemasını izler; her rota bütün kökenlere CORS ile yanıt vermeli ve hepsi statik dosya olabilir.

Protokolün rotaları
GET  /manifest.json                          -> the manifest
GET  /catalog/game/{catalogId}.json          -> { metas: [...] }
GET  /meta/game/{id}.json                    -> { meta }
GET  /play/game/{id}.json                    -> { plays: [...] }
POST {engine.url}/apply                      -> engine reply    (engine mode only)
POST {engine.url}/timeout                    -> engine reply    (engine mode only)
Manifest
Kimlik, sürüm, protokol sürümü camtable: "1", kaynaklar, Kataloglar ve izinler. CamTable onu yüklerken doğrular; validateManifest aynı denetimi senin tarafında yapar.
Kataloglar
Her Katalog, panelin Keşfet sekmesinde bir satır. Hangi oyunun hangi sırada duracağına sen karar verirsin; CamTable hiçbir şeyi sıralamaz. Tür ve oyuncu sayısı filtreleri de senin.
Play Option'lar
Bir oyunu oynamanın bir yolu: oyun sayfanın adresi, oyuncu sayıları, izinler; istersen bir motor, özel sekmeler ve oyun ayarları. Oyunun sayfasında her biri bir Oyna düğmesi olur.

Merkezsiz bir platform

  • Kodun senin sunucunda kalır: CamTable'ın Chrome eklentisi ve sunucusu onu indirmez, saklamaz, çalıştırmaz. CamTable topluluk eklentilerini incelemez, listelemez, önermez.
  • Oyuncular eklentini manifest adresiyle ya da paylaştığın bir Kurulum Bağlantısıyla ekler.
  • Tek para kanalı manifestteki donationUrl. CamTable gelir payı almaz.
  • Bir oda, açıldığı sürümü maç boyunca sabitler: oyun sayfasının adresi, sekmeler, izinler ve motor adresi dahil.

Kurallar ve sınırlar

Yayıncı sensin. Sınırlar baştan yazılı.

  • Yayıncı sensin

    CamTable topluluk eklentilerini barındırmaz, incelemez, listelemez ve tanıtmaz.

  • Sahibi olmadığını kullanma

    Oyun mekanikleri genelde korunmaz, ama isimler, metinler ve görseller korunur. Oyununa ticari bir oyunun adını verme, görselini kullanma. Şikâyet toplayan bir eklenti engel listesine girer.

  • İhtiyacın olmayanı toplama

    Discord kimliklerini, sunucuları ya da kanalları göremezsin. Bunun etrafından dolaşmaya çalışma.

  • Hızlı ve ulaşılabilir ol

    Yavaş ya da bozuk bir eklenti yalnızca kendi oyunlarına zarar verir, ama verir.

Sınırlar

3 sn
Motorun yanıt süresi; host modunda oda sahibinin bir isteği işleme süresi de.
64 KB
Durum ve görünümler için, ayrı ayrı, serileştirilmiş boyut.
16
Bir yanıtın isteyebileceği en fazla zamanlayıcı.
24
Bir Play Option'daki en fazla oyun ayarı alanı.
2–6
Kurallarının adlandırdığı bir fısıltı grubundaki oyuncu sayısı.
15 dk
Oda sahibinin bağlantısı koparsa maç bu kadar bekler; dönmezse biter.

Masa kurulu. Kuralları sen yaz.

Rehber, protokolden barındırmaya her şeyi anlatır. Türkçe özetlerle başla, ayrıntı için İngilizce bölümlere geç.

Oyununu gerçek bir aramada oyna

Kurulum Bağlantısı ve Discord araması için CamTable'ın Chrome eklentisi gerekir.

Chrome'a ekle Chrome Web Mağazası