Spelersaccounts

Geef de spelers van uw game een account dat ze meenemen naar elke Aukimi-game, met opgeslagen spellen die meereizen van het ene apparaat naar het andere, op de dienst van Aukimi of op een eigen server.

In het kort#

Een speler meldt zich eenmaal aan op play.aukimi.com en vindt dat account terug in elke game die met Aukimi is gemaakt, opgeslagen spellen inbegrepen. Uw game vraagt om het account; het krijgt het wachtwoord nooit te zien.

Waarom uw game het wachtwoord nooit ziet#

Iedereen kan een game publiceren. Een game die om een Aukimi-wachtwoord vroeg, zou een perfect geloofwaardige phishingpagina zijn, en geen enkele hoeveelheid goede bedoelingen aan uw kant zou veranderen wat een andere ontwikkelaar zou kunnen uitbrengen.

Dus wordt het wachtwoord getypt op play.aukimi.com en nergens anders. Uw game roept PlayerLoginAsync() aan, er opent een browservenster in de eigen kleuren van Aukimi, de speler keurt het goed, en het venster geeft uw game een token.

Dat token wordt uitgegeven voor uw game alleen. Een token van game A dat aan game B wordt voorgelegd, wordt geweigerd, niet genegeerd, geweigerd. Dat is het punt: het account wordt gedeeld tussen games, de toegang niet. Zonder dit zou één kwaadaardige game de opgeslagen spellen van een speler in alle andere kunnen lezen.

Wat u over een speler ontvangt#

Twee dingen, en niet meer:

U krijgtU krijgt nooit
Een weergavenaam (PlayerName())Het e-mailadres
Een ondoorzichtige id, anders in elke game (PlayerID())Iets dat hen elders identificeert

De id verandert bewust van de ene game naar de andere. Twee ontwikkelaars die hun spelerlijsten vergelijken, kunnen niet zien dat ze naar dezelfde persoon kijken. Het houdt u ook een verwerker in plaats van een verwerkingsverantwoordelijke van die gegevens, wat een juridisch onderscheid is en geen decoratief.

Niets blokkeert de gamelus#

Elk commando dat met het netwerk praat, geeft een jobnummer terug, nooit een resultaat. Uw lus blijft draaien op zestig frames per seconde terwijl het verzoek onderweg is: dat is precies waarom een game niet gewoon kan "wachten op de server".

job = PlayerLoginAsync()

Dan, eenmaal per frame:

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

Geef de job vrij zodra u hem hebt gelezen. Een job die u nooit vrijgeeft, houdt zijn resultaat de rest van de sessie in het geheugen. Niets breekt, niets waarschuwt u, en het lek toont zich pas in een lange speelsessie.

Spelen zonder account#

Niet iedereen wil zich aanmelden voordat ze een game proberen. PlayerGuestAsync(name$) maakt een account zonder e-mail, bewaard in deze browser.

Het is een echt account: het slaat op, het laadt, en het kan later geclaimd worden, de speler voegt een e-mailadres en een wachtwoord toe, en de bestaande opgeslagen spellen volgen mee zonder te verhuizen.

De eerlijke prijs: de sitegegevens van de browser wissen, verliest dat account, en er is geen manier om het terug te krijgen. Dat is de prijs van "geen aanmelding", en uw game moet dat zeggen in plaats van de speler het te laten ontdekken. PlayerIsGuest() is er precies voor die zin.

Opslaan#

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

Het opgeslagen spel is JSON in uw eigen vorm, bewaard tegen het paar (deze speler, deze game). Het volgt hen naar een andere browser, een andere machine, een ander platform.

Voor een handvol waarden zijn SetCloudDataVariable() en CloudDataVariable() eenvoudiger: geen job, geen JSON. Controleer eerst CloudDataAllowed(): het geeft 0 terug wanneer er geen speler is aangemeld, en toch schrijven zou stilzwijgend nergens heen gaan.

Het scherm tekenen#

Aukimi tekent geen aanmeldformulier. Een formulier samengesteld door de engine zou er altijd uitzien als een webpagina die op een pixelart-game is gedropt, en het zou het enige deel van uw game zijn dat u niet kunt herstijlen.

U tekent het zelf. Het enige stukje dat uit de browser moet komen, is tekstinvoer, dus CreateEditBox() geeft u een echt invoerveld dat u zelf positioneert:

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

De demo Player Account in de voorbeeldenlijst van de Engine is een volledig werkend scherm in ongeveer honderd regels. Open het, lees het, en vervang dan elke Print() door uw eigen artwork.

Voordat dit alles werkt#

De game moet gedeclareerd zijn vanuit uw Aukimi-account, onder My games (aukimi.com/app/games): een titel, het adres waar ze gespeeld kan worden, en de adressen waarnaar uw game mag terugkeren. Tot dan geeft PlayerAvailable() 0 terug, en een goede game zegt "accounts zijn niet beschikbaar" in plaats van te lijken vast te lopen.

Datzelfde scherm is waar u ziet wie er speelt. Lees de getallen voor wat ze zijn: het telt spelers die zich hebben aangemeld en gestarte sessies, nooit gespeelde games. Een game die nooit iemand vraagt zich aan te melden, toont daar niets, en het scherm zegt dat ook in plaats van een stille nul te tonen.

Uw eigen accountserver gebruiken#

Alles hierboven praat met de accountdienst van Aukimi. Als u uw game op uw eigen server host, kunnen dezelfde twaalf commando's in plaats daarvan met uw dienst praten, en uw script verandert geen letter.

In de Engine: paneel Multiplayer → sectie Player accounts → kies My own server → vul één veld in, het adres van uw server. Dat adres is een instelling van de scène, dus twee games kunnen twee verschillende diensten gebruiken.

Twee manieren om een speler aan te melden#

De keuze wordt in uw script gemaakt, niet in een instelling. Beide vormen bestaan bij elke server waar u naar wijst.

Het venster (wat u al kent)#

job = PlayerLoginAsync()

Er opent een venster, de speler meldt zich daar aan, en het geeft uw game het recht om namens hen te handelen terug. Bij de dienst van Aukimi is dat venster play.aukimi.com. Met uw eigen server is die pagina van u om te bouwen.

Rechtstreeks, met een gebruikersnaam en een wachtwoord#

job = PlayerLoginAsync(username$, password$)

Geen venster. Uw game leest wat de speler op uw eigen scherm heeft getypt en stuurt het naar uw server. Eenvoudiger om te schrijven, en het laat u de look van uw game van begin tot eind behouden.

Waarschuwing: in deze vorm reist het wachtwoord van uw game naar uw server zoals het is getypt. Twee gevolgen, allebei vast: het adres van uw server moet beginnen met https:// (alleen een test op uw eigen machine is uitgezonderd), en deze vorm is alleen ooit bedoeld voor een server die u zelf bezit.

play.aukimi.com weigert dit, met opzet. Aukimi wil nooit in de positie zitten om het wachtwoord van een speler te zien, en dat geldt ook voor een game die u niet zelf hebt geschreven.

De twee keuzes staan los van de instelling: een zelfgebouwde server mag best alleen het venster aanbieden, en nooit rechtstreeks een wachtwoord accepteren.

Een concreet voorbeeld#

Een game met een eigen "Sign in"-scherm: twee tekstvelden getekend door de game, één knop, en dit achter de knop.

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

Alles na het aanmelden is identiek aan de rest van deze pagina: PlayerSaveAsync, PlayerLoadAsync, PlayerName en de andere weten niet, en het kan hen niet schelen, welke server heeft geantwoord.

Wat uw server moet beantwoorden#

Vier adressen zijn vereist, welke aanmeldvorm u ook aanbiedt:

Waarvoor het dientWat de game verwacht
Als gast spelenEen account zonder e-mail teruggeven
Wie is deze spelerDe weergavenaam, de id, of ze een gast zijn
Het opgeslagen spel lezenDe opgeslagen gegevens
Het opgeslagen spel schrijvenOpslaan wat de game verstuurt

Dan, afhankelijk van wat u kiest aan te bieden:

  • De vensterversie heeft een aanmeldpagina op uw server nodig, die de game vertelt wie er is aangemeld zodra het klaar is.
  • De rechtstreekse versie heeft nog één adres nodig, dat een gebruikersnaam en een wachtwoord aanneemt en ja of nee antwoordt.

De precieze adressen, de vorm van elk antwoord en de foutcodes staan in de repository, in docs/engine-player-accounts.md. Dat bestand is het contract; deze pagina is de kaart.

Opmerking: niets hiervan werkt in een native export. De Player*-commando's hebben een server nodig om mee te praten en een browser om doorheen te praten, en een native build heeft geen van beide.

De commando's#

CommandoWat het doet
PlayerAvailable()Is de accountdienst geconfigureerd voor deze game
PlayerLoginAsync()Opent het aanmeldvenster. Geeft een job terug
PlayerLoginAsync(user, pass)Meldt rechtstreeks aan, alleen op uw eigen server. Geeft een job terug
PlayerGuestAsync()Maakt een account zonder e-mail. Geeft een job terug
PlayerLoggedIn()Is er nu iemand aangemeld
PlayerName()Hun weergavenaam
PlayerID()Hun ondoorzichtige id, specifiek voor deze game
PlayerIsGuest()Is dit een account zonder e-mail
PlayerSaveAsync()Schrijft het opgeslagen spel. Geeft een job terug
PlayerLoadAsync()Leest het terug. Geeft een job terug
PlayerRefreshAsync()Vernieuwt het token voordat het verloopt
PlayerLogout()Meldt af op dit apparaat
PlayerLastError()Waarom de laatste aanroep is mislukt