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ız | Asla 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çin | Oyunun beklediği |
|---|---|
| Misafir olarak oynamak | E-postasız bir hesap vermek |
| Bu oyuncu kim | Görünen ad, kimlik, misafir olup olmadığı |
| Kaydı okumak | Kaydedilen veri |
| Kaydı yazmak | Oyunun 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#
| Komut | Ne 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 |