Oyuncu hesapları

Oyununuzun oyuncularına, Aukimi ile yapılmış her oyunda tuttukları, bir cihazdan diğerine onları izleyen kayıtlarla, Aukimi'nin servisinde ya da kendi sunucunuzda bir hesap verin.

Tek cümleyle#

Bir oyuncu play.aukimi.com üzerinde bir kez giriş yapar ve bu hesabı Aukimi ile yapılmış her oyunda, kayıtlar dahil, karşısında bulur. Oyununuz hesabı ister; şifreyi asla ele almaz.

Oyununuz şifreyi neden hiç görmez#

Herkes bir oyun yayınlayabilir. Bir Aukimi şifresi isteyen bir oyun, kusursuz derecede ikna edici bir kimlik avı sayfası olurdu ve sizin iyi niyetiniz, başka bir geliştiricinin ne yayınlayabileceğini hiç değiştirmezdi.

Bu yüzden şifre yalnızca play.aukimi.com üzerinde yazılır, başka hiçbir yerde değil. Oyununuz PlayerLoginAsync()'i çağırır, Aukimi'nin kendi renklerinde bir pencere açılır, oyuncu onaylar ve pencere oyununuza bir jeton verir.

Bu jeton yalnızca sizin oyununuz için geçerlidir. A oyununun jetonu B oyununa sunulduğunda reddedilir; görmezden gelinmez, reddedilir. Mesele tam olarak budur: hesap oyunlar arasında paylaşılır, erişim paylaşılmaz. Bu olmasaydı, kötü niyetli bir oyun, bir oyuncunun kayıtlarını diğer tüm oyunlarda okuyabilirdi.

Bir oyuncu hakkında aldığınız şey#

İki şey, ve fazlası değil:

AldığınızAsla almadığınız
Bir görünen ad (PlayerName())E-posta adresi
Her oyunda farklı olan opak bir kimlik (PlayerID())Onları başka yerde tanımlayacak herhangi bir şey

Kimlik, bilerek bir oyundan diğerine değişir. Oyuncu listelerini karşılaştıran iki geliştirici, aynı kişiye baktıklarını anlayamaz. Bu, sizi ayrıca bu verinin bir denetleyicisi değil, işleyicisi olarak tutar; bu hukuki bir ayrımdır, süs değil.

Hiçbir şey oyun döngüsünü durdurmaz#

Ağla konuşan her komut, asla bir sonuç değil, bir görev numarası döndürür. İstek uçuştayken döngünüz saniyede altmış karede çalışmaya devam eder; bir oyunun "sunucuyu bekle"yemeyecek olmasının tüm nedeni de budur.

job = PlayerLoginAsync()

Sonra, kare başına bir kez:

etat$ = PlatformJobState(job)
if etat$ = "done"
    resultat$ = PlatformJobResult(job)
    PlatformJobRelease(job)
endif
if etat$ = "error"
    Print(PlatformJobError(job))
    PlatformJobRelease(job)
endif

Görevi okuduktan sonra serbest bırakın. Asla serbest bırakılmayan bir görev, sonucunu oturumun geri kalanı boyunca bellekte tutar. Hiçbir şey bozulmaz, hiçbir şey sizi uyarmaz, ve sızıntı yalnızca uzun bir oynanış oturumunda ortaya çıkar.

Hesap olmadan oynamak#

Herkes bir oyunu denemeden önce kaydolmak istemez. PlayerGuestAsync(name$), e-postasız, bu tarayıcıda tutulan bir hesap oluşturur.

Bu gerçek bir hesaptır: kaydeder, yükler ve daha sonra sahiplenilebilir; oyuncu bir e-posta ve bir şifre ekler, ve mevcut kayıtlar taşınmadan onu izler.

Dürüst olmak gerekirse: tarayıcının site verilerini temizlemek bu hesabı kaybettirir, ve onu geri getirecek bir yol yoktur. "Kayıt yok"un bedeli budur, ve oyununuz bunu, oyuncunun kendi kendine keşfetmesine izin vermek yerine, söylemelidir. PlayerIsGuest(), tam olarak bu cümle için vardır.

Kaydetmek#

job = PlayerSaveAsync(donnees$)
job = PlayerLoadAsync()

Kayıt, kendi biçiminizde bir JSON'dur; (bu oyuncu, bu oyun) çiftine karşı saklanır. Onu başka bir tarayıcıya, başka bir makineye, başka bir platforma izler.

Bir avuç değer için, SetCloudDataVariable() ve CloudDataVariable() daha basittir; görev yok, JSON yok. Önce CloudDataAllowed()'i kontrol edin: hiç kimse giriş yapmamışken 0 döndürür, ve yine de yazmak sessizce hiçbir yere gitmez.

Ekranı çizmek#

Aukimi hiçbir giriş formu çizmez. Motor tarafından oluşturulan bir form, her zaman bir pixel-art oyunun üzerine bırakılmış bir web sayfası gibi görünürdü, ve bu, oyununuzun yeniden giydiremeyeceğiniz tek parçası olurdu.

Onu siz çizersiniz. Tarayıcıdan gelmesi gereken tek parça metin girişidir; bu yüzden CreateEditBox() size kendiniz konumlandırdığınız gerçek bir giriş alanı verir:

CreateEditBox(1)
EditBoxPosition(1, 20, 42)
EditBoxSize(1, 60, 8)
nom$ = EditBoxText(1)

Engine'in örnek listesindeki Player Account demosu, yaklaşık yüz satırda tam çalışan bir ekrandır. Onu açın, okuyun, sonra her Print()'i kendi görselinizle değiştirin.

Bunların hiçbiri çalışmadan önce#

Oyun, Aukimi hesabınızdan, My games altında (aukimi.com/app/games) bildirilmelidir: bir başlık, oynanabileceği adres, ve oyununuzun geri dönmesine izin verilen adresler. Bu yapılana kadar PlayerAvailable() 0 döndürür, ve iyi bir oyun, kilitlenmiş gibi görünmek yerine "hesaplar şu anda kullanılamıyor" der.

Kimin oynadığını gördüğünüz ekran da budur. Sayıları oldukları gibi okuyun: giriş yapmış oyuncuları ve başlatılmış oturumları sayar, asla oynanan oyunları saymaz. Hiç kimseye giriş yapmasını istemeyen bir oyun orada hiçbir şey göstermez, ve ekran, sessiz bir sıfır göstermek yerine bunu söyler.

Kendi hesap sunucunuzu kullanmak#

Yukarıdakilerin hepsi Aukimi'nin hesap servisiyle konuşur. Oyununuzu kendi sunucunuzda barındırırsanız, aynı on iki komut bunun yerine sizin servisinizle konuşabilir, ve betiğiniz tek bir satır bile değişmez.

Engine'de: Multiplayer paneli → Player accounts bölümü → My own server'ı seçin → tek bir alanı, sunucunuzun adresini doldurun. Bu adres, sahnenin bir ayarıdır: bu yüzden iki oyun iki farklı servis kullanabilir.

Bir oyuncuyu giriş yaptırmanın iki yolu#

Seçim, bir ayarda değil, betiğinizde yapılır. Hangi sunucuyu hedeflerseniz hedefleyin, her iki biçim de vardır.

Pencere (zaten bildiğiniz)#

job = PlayerLoginAsync()

Bir pencere açılır, oyuncu orada giriş yapar, ve pencere oyununuza onun adına hareket etme hakkını verir. Aukimi'nin servisiyle bu pencere play.aukimi.com'dur. Kendi sunucunuzla, bu sayfayı inşa etmek size kalmıştır.

Doğrudan, bir kullanıcı adı ve şifreyle#

job = PlayerLoginAsync(username$, password$)

Pencere yok. Oyununuz, oyuncunun kendi ekranınızda yazdığını okur ve sunucunuza gönderir. Yazması daha basittir, ve oyununuzun görünümünü baştan sona korumanızı sağlar.

Uyarı: bu biçimde, şifre oyununuzdan sunucunuza yazıldığı gibi gider. İkisi de kesin olan iki sonuç: sunucunuzun adresi https:// ile başlamalıdır (yalnızca kendi makinenizdeki bir deneme buna muaf tutulur), ve bu biçim yalnızca sahibi olduğunuz bir sunucu için anlamlıdır.

play.aukimi.com, bunu bilerek reddeder. Aukimi, bir oyuncunun şifresini görebileceği bir konumda olmak istemez, ve yazmadığınız bir oyun da bunu istememelidir.

İki seçim ayardan bağımsızdır: ev yapımı bir sunucu, yalnızca pencereyi sunup asla bir şifreyi doğrudan kabul etmeyebilir.

Somut bir örnek#

Kendi "Sign in" ekranına sahip bir oyun: oyun tarafından çizilen iki metin alanı, bir düğme, ve düğmenin arkasında şu:

job = PlayerLoginAsync(typedName$, typedPassword$)
DO
    etat$ = PlatformJobState(job)
    if etat$ = "done"
        PlatformJobRelease(job)
        Print("Welcome " + PlayerName())
    endif
    if etat$ = "error"
        PlatformJobRelease(job)
        Print(PlayerLastError())
    endif
    Sync()
LOOP

Giriş sonrasındaki her şey, bu sayfanın geri kalanıyla aynıdır: PlayerSaveAsync, PlayerLoadAsync, PlayerName ve diğerleri, hangi sunucunun yanıt verdiğini ne bilir ne de umursar.

Sunucunuzun yanıtlaması gereken şey#

Hangi girişi sunarsanız sunun, dört adres zorunludur:

Ne içinOyunun beklediği
Misafir olarak oynamakE-postasız bir hesap vermek
Bu oyuncu kimGörünen ad, kimlik, misafir olup olmadığı
Kaydı okumakKaydedilen veri
Kaydı yazmakOyunun gönderdiğini saklamak

Sonra, ne sunmayı seçtiğinize bağlı olarak:

  • Pencere biçimi, sunucunuzda, işi bittiğinde kimin giriş yaptığını oyuna söyleyen bir giriş sayfası gerektirir.
  • Doğrudan biçim, bir kullanıcı adı ve şifre alıp evet ya da hayır yanıtlayan bir adres daha gerektirir.

Tam adresler, her yanıtın biçimi ve hata kodları depoda, docs/engine-player-accounts.md içindedir. O dosya sözleşmedir; bu sayfa haritadır.

Not: bunların hiçbiri native bir dışa aktarımda çalışmaz. Player* komutları konuşacak bir sunucuya ve konuşacağı bir tarayıcıya ihtiyaç duyar, ve native bir derlemede ikisi de yoktur.

Komutlar#

KomutNe yapar
PlayerAvailable()Bu oyun için hesap servisi yapılandırılmış mı
PlayerLoginAsync()Giriş penceresini açar. Bir görev döndürür
PlayerLoginAsync(user, pass)Yalnızca kendi sunucunuzda, doğrudan giriş yapar. Bir görev döndürür
PlayerGuestAsync()E-postasız bir hesap oluşturur. Bir görev döndürür
PlayerLoggedIn()Şu anda giriş yapmış biri var mı
PlayerName()Görünen adları
PlayerID()Bu oyuna özgü opak kimlikleri
PlayerIsGuest()Bu, e-postasız bir hesap mı
PlayerSaveAsync()Kaydı yazar. Bir görev döndürür
PlayerLoadAsync()Onu geri okur. Bir görev döndürür
PlayerRefreshAsync()Jetonu süresi dolmadan yeniler
PlayerLogout()Bu cihazda çıkış yapar
PlayerLastError()Son çağrının neden başarısız olduğu