Spelarkonton
Ge spelarna i ditt spel ett konto de behåller i varje Aukimi-spel, med sparfiler som följer med dem från en enhet till nästa, på Aukimis tjänst eller på en egen server.
I korthet#
En spelare loggar in en gång på play.aukimi.com och hittar det kontot i varje spel gjort med Aukimi, sparfiler inkluderat. Ditt spel frågar efter kontot; det hanterar aldrig lösenordet.
Varför ditt spel aldrig ser lösenordet#
Vem som helst kan publicera ett spel. Ett spel som frågade efter ett Aukimi-lösenord skulle vara en perfekt övertygande nätfiskesida, och ingen mängd goda avsikter från din sida skulle ändra vad en annan utvecklare skulle kunna skicka ut.
Så lösenordet skrivs på play.aukimi.com och ingen annanstans. Ditt spel
anropar PlayerLoginAsync(), ett webbläsarfönster öppnas i Aukimis egna
färger, spelaren godkänner, och fönstret lämnar över en token till ditt spel.
Den token utfärdas bara för ditt spel. En token för spel A som visas för spel B avvisas, inte ignoreras, avvisas. Det är poängen: kontot delas mellan spel, åtkomsten gör det inte. Utan det här skulle ett skadligt spel kunna läsa en spelares sparfiler i alla de andra.
Vad du får veta om en spelare#
Två saker, och inte mer:
| Du får | Du får aldrig |
|---|---|
Ett visningsnamn (PlayerName()) | E-postadressen |
Ett ogenomskinligt id, olika i varje spel (PlayerID()) | Något som identifierar dem någon annanstans |
Id:t ändras från ett spel till nästa med flit. Två utvecklare som jämför sina spelarlistor kan inte se att de tittar på samma person. Det håller dig också som en behandlare snarare än en personuppgiftsansvarig för den datan, vilket är en juridisk distinktion och inte en dekorativ.
Inget blockerar spelloopen#
Varje kommando som pratar med nätverket returnerar ett jobbnummer, aldrig ett resultat. Din loop fortsätter köra i sextio bildrutor per sekund medan begäran är på väg, vilket är hela anledningen till att ett spel inte helt enkelt kan "vänta på servern".
job = PlayerLoginAsync()
Sedan, en gång per bildruta:
etat$ = PlatformJobState(job)
if etat$ = "done"
resultat$ = PlatformJobResult(job)
PlatformJobRelease(job)
endif
if etat$ = "error"
Print(PlatformJobError(job))
PlatformJobRelease(job)
endif
Släpp jobbet så snart du har läst det. Ett jobb du aldrig släpper håller sitt resultat i minnet för resten av sessionen. Inget går sönder, inget varnar dig, och läckan visar sig bara i en lång spelsession.
Att spela utan ett konto#
Alla vill inte registrera sig innan de provar ett spel. PlayerGuestAsync(name$)
skapar ett konto utan e-post, sparat i den här webbläsaren.
Det är ett riktigt konto: det sparar, det laddar, och det kan hävdas senare, spelaren lägger till en e-post och ett lösenord, och de befintliga sparfilerna följer med utan att flyttas.
Den ärliga hakan: att rensa webbläsarens webbplatsdata förlorar det kontot, och
det finns inget sätt att återfå det. Det är priset för "inget registrerande",
och ditt spel bör säga det i stället för att låta spelaren upptäcka det.
PlayerIsGuest() finns till just för den meningen.
Att spara#
job = PlayerSaveAsync(donnees$)
job = PlayerLoadAsync()
Sparfilen är JSON i din egen form, lagrad mot paret (den här spelaren, det här spelet). Den följer med till en annan webbläsare, en annan maskin, en annan plattform.
För en handfull värden är SetCloudDataVariable() och CloudDataVariable()
enklare, inget jobb, ingen JSON. Kontrollera CloudDataAllowed() först: den
returnerar 0 när ingen spelare är inloggad, och att ändå skriva skulle tyst gå
ingenstans.
Att rita skärmen#
Aukimi ritar inget inloggningsformulär. Ett formulär sammansatt av motorn skulle alltid se ut som en webbsida släppt ovanpå ett pixelkonstspel, och det skulle vara den enda delen av ditt spel du inte kunde omstila.
Du ritar det. Den enda delen som måste komma från webbläsaren är textinmatning,
så CreateEditBox() ger dig ett riktigt inmatningsfält du placerar själv:
CreateEditBox(1)
EditBoxPosition(1, 20, 42)
EditBoxSize(1, 60, 8)
nom$ = EditBoxText(1)
Demot Player Account i Engines exempellista är en komplett fungerande skärm
på ungefär hundra rader. Öppna det, läs det, ersätt sedan varje Print() med
din egen bildkonst.
Innan något av detta fungerar#
Spelet måste deklareras från ditt Aukimi-konto, under My games
(aukimi.com/app/games): en titel, adressen där det kan spelas, och adresserna
ditt spel får återvända till. Fram tills dess returnerar PlayerAvailable() 0,
och ett bra spel säger "accounts are not available" i stället för att verka
hänga sig.
Samma skärm är där du ser vem som spelar. Läs siffrorna för vad de är: den räknar spelare som loggat in och sessioner startade, aldrig spel spelade. Ett spel som aldrig ber någon logga in visar ingenting där, och skärmen säger det i stället för att visa en tyst nolla.
Att använda din egen kontoserver#
Allt ovan pratar med Aukimis kontotjänst. Om du hostar ditt spel på din egen server kan samma tolv kommandon prata med din tjänst i stället, och ditt skript ändras inte med en enda rad.
I Engine: panelen Multiplayer → sektionen Player accounts → välj My own server → fyll i ett fält, adressen till din server. Den adressen är en inställning för scenen, så att två spel kan använda två olika tjänster.
Två sätt att logga in en spelare#
Valet görs i ditt skript, inte i en inställning. Båda formerna finns oavsett vilken server du pekar mot.
Fönstret (det du redan känner till)#
job = PlayerLoginAsync()
Ett fönster öppnas, spelaren loggar in där, och det lämnar tillbaka till ditt
spel rätten att agera för deras räkning. Med Aukimis tjänst är det fönstret
play.aukimi.com. Med din egen server är den sidan din att bygga.
Direkt, med ett användarnamn och ett lösenord#
job = PlayerLoginAsync(username$, password$)
Inget fönster. Ditt spel läser vad spelaren skrev på din egen skärm och skickar det till din server. Enklare att skriva, och det låter dig behålla ditt spels utseende från början till slut.
Varning: i den här formen färdas lösenordet från ditt spel till din server som skrivet. Två konsekvenser, båda bestämda: adressen till din server måste börja med
https://(bara ett test på din egen maskin är undantaget), och den här formen är bara någonsin avsedd för en server du äger.
play.aukimi.comavvisar den, med flit. Aukimi vill aldrig vara i en position att se en spelares lösenord, och det borde inte heller ett spel du inte skrev.
De två valen är oberoende av inställningen: en hemmagjord server kan gott erbjuda bara fönstret, och aldrig acceptera ett lösenord direkt.
Ett konkret exempel#
Ett spel med sin egen "Logga in"-skärm: två textfält ritade av spelet, en knapp, och det här bakom knappen.
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
Allt efter inloggningen är identiskt med resten av den här sidan:
PlayerSaveAsync, PlayerLoadAsync, PlayerName och de andra vet inte, och
bryr sig inte om, vilken server som svarade.
Vad din server måste svara på#
Fyra adresser krävs, oavsett vilken inloggning du erbjuder:
| Vad det är till för | Vad spelet förväntar sig |
|---|---|
| Spela som gäst | Lämna tillbaka ett konto utan e-post |
| Vem är den här spelaren | Visningsnamnet, id:t, om de är en gäst |
| Läs sparfilen | Den sparade datan |
| Skriv sparfilen | Lagra vad spelet skickar |
Sedan, beroende på vad du väljer att erbjuda:
- Fönsterformen behöver en inloggningssida på din server, som talar om för spelet vem som loggade in när det är klart.
- Direktformen behöver en adress till, som tar ett användarnamn och ett lösenord och svarar ja eller nej.
De exakta adresserna, formen på varje svar och felkoderna finns i
repositoriet, i docs/engine-player-accounts.md. Den filen är kontraktet;
den här sidan är kartan.
Obs: inget av detta fungerar i en native-export.
Player*-kommandona behöver en server att prata med och en webbläsare att prata genom, och ett native-bygge har ingetdera.
Kommandona#
| Kommando | Vad det gör |
|---|---|
PlayerAvailable() | Är kontotjänsten konfigurerad för det här spelet |
PlayerLoginAsync() | Öppnar inloggningsfönstret. Returnerar ett jobb |
PlayerLoginAsync(user, pass) | Loggar in direkt, bara på din egen server. Returnerar ett jobb |
PlayerGuestAsync() | Skapar ett konto utan e-post. Returnerar ett jobb |
PlayerLoggedIn() | Är någon inloggad just nu |
PlayerName() | Deras visningsnamn |
PlayerID() | Deras ogenomskinliga id, specifikt för det här spelet |
PlayerIsGuest() | Är det här ett konto utan e-post |
PlayerSaveAsync() | Skriver sparfilen. Returnerar ett jobb |
PlayerLoadAsync() | Läser tillbaka den. Returnerar ett jobb |
PlayerRefreshAsync() | Förnyar token innan den går ut |
PlayerLogout() | Loggar ut på den här enheten |
PlayerLastError() | Varför det senaste anropet misslyckades |